[Pitch] Add the DefaultConstructible protocol to the standard library

Well, reflection is a huge performance drop. Protocol conformance is way
better.

···

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used independently
of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol? Wouldn't
the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

>> https://vapor.github.io/documentation/fluent/model.html

>> https://github.com/blitzagency/amigo-swift

>>

>>

>> In general I think the best showcase is generic factories.

>>

>> On Mon, 26 Dec 2016 at 9:02 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 10:18 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Usually it's a generic function that needs to return a value from some

>> other function or a default value (zero) in a case of some conditions.

>> Optional value is an arguable solution in quite some scenarios. Afaik,

>> sometimes it can be used for optional resolution.

>>

>>

>> Right, I'd agree that Optional is the idiomatic way to do it. Afaict,

>> there's not much you can do with a default value that you couldn't with

>> nil, unless you have some guarantee as to _what_ that default is;
however,

>> I'd expect that in every case that you can rely on a guarantee about a

>> default value which would be more useful than nil, it's going to require

>> more specific knowledge of your type than an all-encompassing

>> `DefaultConstructible` can provide.

>>

>> Also, generic factories. Widely used in ORM solutions.

>>

>>

>> Can you elaborate on this? Why is Optional not a solution here?

>>

>>

>> As mentioned above, algorythmical stuff that requires Zero.

>>

>>

>> I'm still not convinced there exist credible use cases that need to be

>> generic over both collections and floating point, for instance. In
fact, in

>> my experience, there are few math-heavy algorithms where one can ignore

>> even the distinction between integers and binary floating point. By the

>> time you get down to matrix math, you start to run into difficulties
that

>> require separate implementations for Float and Double.

>>

>> On Mon, 26 Dec 2016 at 8:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> Can you give some examples of what you used this approach to do?

>>

>>

>> On Sun, Dec 25, 2016 at 9:49 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> +1 to this approach. I remember I had to create it on my own for my

>> projects. Would be nice to have it out of the box.

>>

>> On Mon, 26 Dec 2016 at 8:11 Adam Nemecek via swift-evolution < > > > >> swift-evolution@swift.org> wrote:

>>

>> > Yes, those particular types have initializers that take no arguments.

>> That does not address my question. You merely restated your initial

>> observation that many types in Swift have implemented `init()`.

>>

>> Right, it's an empirical argument.

>>

>> > I didn't think the value returned by `init()` was regarded as any sort

>> of zero--or even any sort of "default." In fact, some types in
Foundation

>> have a static property called `default` distinct from `init()`.

>>

>> Let's not talk about those then. This would not apply to every single
type

>> in existence, as I've stated previously.

>>

>> > It gives you something different every time. How can this be squared

>> with your stated motivation regarding concepts of zero and concepts of

>> equality?

>>

>> Due to the fact that it's a resource, not a value. As I've stated above,

>> not all of this applies to types that are more resource-like.

>>

>> > Or, it's what you get because that's the most trivial possible string.

>> Quite simply, I do not think the designer of most types that implement

>> `init()` have paused to wonder whether the value that you get is the

>> identity element associated with the most useful and prominent operation

>> that can be performed on that type. I certainly never have.

>>

>> This is an appeal to tradition.

>>

>> > The statement I wrote was in JavaScript, so I'm not sure what you mean

>> by returning an optional. `[].reduce((a, b) => a + b)` results in an

>> error in JavaScript. In Swift, such a function may also be implemented
with

>> a precondition that the array is not empty and would not return an
optional.

>>

>> I was talking about their analogous swift implementations.

>>

>> > Can you give an example of an algorithm dealing with tensors where you

>> would use a `DefaultConstructible` generic over all types that have

>> `init()`, as opposed to working with the existing `Integer`,

>> `FloatingPoint`, and other numerical protocols?

>>

>> If it's implemented as either nested collections or numbers.

>>

>>

>>

>> On Sun, Dec 25, 2016 at 6:00 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 7:30 PM, Adam Nemecek <adamnemecek@gmail.com> > > > >> wrote:

>>

>> > Is it well settled, either in Swift or in C++/Rust/etc., that the
value

>> returned by a default initializer/constructor is regarded as an identity

>> element or zero?

>>

>> Int() == 0, String() == "" so to some extent by convention, a lot of
types

>> have a default value as is.

>>

>>

>> Yes, those particular types have initializers that take no arguments.
That

>> does not address my question. You merely restated your initial
observation

>> that many types in Swift have implemented `init()`.

>>

>> I didn't think the value returned by `init()` was regarded as any sort
of

>> zero--or even any sort of "default." In fact, some types in Foundation
have

>> a static property called `default` distinct from `init()`. In Rust, the

>> Default trait requires a function called `default()`, which is
documented

>> as being useful when you want "some kind of default value, and don't

>> particularly care what it is."

>>

>> I was asking whether there's some understanding, of which I've been

>> unaware, that the result of `init()` (or the equivalent in other
languages)

>> is expected to be some sort of zero or an identity element. I'm not
aware

>> of any evidence to that effect. Are you?

>>

>> > Is the thread that I get by writing `let t = Thread()` some kind of
zero

>> in any reasonable sense of the word?

>>

>> DefaultConstructibility makes less sense for types that represent some

>> sort of resource but make sense for things that are values. But even in

>> this case, Thread() gives you a default value for example if you are

>> working with a resizable collection of threads.

>>

>>

>> It gives you something different every time. How can this be squared
with

>> your stated motivation regarding concepts of zero and concepts of
equality?

>>

>> A better question is why does thread currently implement a default

>> constructor?

>>

>>

>> It's an initializer that takes no arguments, because none are needed
for a

>> new thread. How else would you write it?

>>

>> > Do you mean to argue that for an integer the additive identity should
be

>> considered "more prominent and useful" than the multiplicative identity?

>> I'm not aware of any mathematical justification for such a conclusion.

>>

>> I do. The justification is that if I call the default constructor of Int

>> currently, I get the value of 0.

>>

>>

>> This is backwards. Why do you believe that the value you obtain from

>> `init()` is intended to be an identity element at all, let alone the
most

>> important one? (It's also circular reasoning. Since `init()` only ever

>> gives you one value at a time, by your reasoning it demonstrates that
every

>> type must have one "more prominent and useful" identity, which is
begging

>> the question.)

>>

>> Which means that the binary operation must be addition.

>>

>>

>> Based on the value of `Int.init()`, you conclude that addition of
integers

>> is a "more prominent and useful" operation than multiplication? Again,
this

>> is backwards. Rather, we know that each numerical type belongs to
multiple

>> ring algebras; there is no basis for reckoning any as "more useful."
Since

>> `init()` can only ever give us one value at a time, we know that
`init()`

>> cannot give a value that is a meaningful default with respect to any

>> particular operation.

>>

>> If I call String() I get "" which is the identity of the + String

>> operation.

>>

>>

>> Or, it's what you get because that's the most trivial possible string.

>> Quite simply, I do not think the designer of most types that implement

>> `init()` have paused to wonder whether the value that you get is the

>> identity element associated with the most useful and prominent operation

>> that can be performed on that type. I certainly never have.

>>

>> > Going to your original example, I should add: other languages provide
a

>> version of `reduce` that doesn't require an initial result (for
instance,

>> JavaScript). In JavaScript, `[1, 2, 3].reduce((a, b) => a + b)` uses the

>> element at array index 0 as the initial result, and the accumulator

>> function is invoked starting with the element at array index 1. This is

>> precisely equivalent to having `reduce` use the additive identity as the

>> default initial result when + is the accumulator function and the

>> multiplicative identity when * is the accumulator function (with the

>> accumulator function being invoked starting with the element at array
index

>> 0). It does not require a DefaultConstructible protocol. What more

>> ergonomic solution could be implemented using a monoidic wrapper type?

>>

>> These two will have different signatures. The reduce you describe
returns

>> an optional,

>>

>>

>> The statement I wrote was in JavaScript, so I'm not sure what you mean
by

>> returning an optional. `[].reduce((a, b) => a + b)` results in an error

>> in JavaScript. In Swift, such a function may also be implemented with a

>> precondition that the array is not empty and would not return an
optional.

>>

>> the other one would returns the default value.

>>

>>

>> In what scenario would you prefer to propagate a default after reducing
a

>> potential empty collection _without supplying an explicit default_ for
that

>> operation? This would certainly violate the Swift convention of not

>> defaulting to zero and, I suspect, most users of Swift would not regard

>> that as ergonomic at all.

>>

>>

>> Fundamentally the default constructibles are useful in numerical

>> computations e..g. dealing with tensors.

>>

>>

>> Can you give an example of an algorithm dealing with tensors where you

>> would use a `DefaultConstructible` generic over all types that have

>> `init()`, as opposed to working with the existing `Integer`,

>> `FloatingPoint`, and other numerical protocols? (I should also add,
FWIW, I

>> have never seen a generic algorithm written for integers or FP types
that

>> has preferred the use of `T()` over `0`.)

>>

>>

>> On Sun, Dec 25, 2016 at 3:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 5:27 PM, Adam Nemecek <adamnemecek@gmail.com> > > > >> wrote:

>>

>> > *Which* APIs become more ergonomic?

>>

>> I'll get back to this question in a second if I may. This would be a

>> longer discussion and I first want to make sure that before we get into
the

>> details that there is a possibility of this being introduced (I'm
asking if

>> violating the no zero defaults is more important than slightly more

>> ergonomic APIs). But to give a broad answer I think that the concept of
a

>> zero is closely related to the concept of equality (and all the things
that

>> build up on equality such as comparability and negation).

>>

>> > 1) How does this square with Swift’s general philosophy to not default

>> initialize values to “zero”?

>>

>> I actually wasn't aware of this philosophy. Despite this philosophy,
look

>> at how many types actually currently implement a default constructor.

>>

>>

>> (Not a rhetorical question:) Is it well settled, either in Swift or in

>> C++/Rust/etc., that the value returned by a default
initializer/constructor

>> is regarded as an identity element or zero? Is the thread that I get by

>> writing `let t = Thread()` some kind of zero in any reasonable sense of
the

>> word?

>>

>>

>> Also can I ask what's the motivation behind this philosophy?

>> I think that in Swift, default constructibility makes complete sense for

>> (most?) structs, maybe less so for classes.

>>

>> > 2) To your original example, it isn’t immediately clear to me that

>> reduce should choose a default identity. Some types (e.g. integers and
FP)

>> belong to multiple different ring algebras, and therefore have different

>> identity values that correspond to the relevant binary operations.

>>

>> This is a good point that I've considered as well but felt that for the

>> most part, there is one particular identity and associated operation
that

>> is more prominent and useful than others. Furthermore, modeling
different

>> algebras isn't mutually exclusive with writing generic algorithms that
rely

>> on this protocol, you can always introduce some monoidic wrapper type
that

>> defines the more appropriate default value and operation.

>>

>>

>> Do you mean to argue that for an integer the additive identity should be

>> considered "more prominent and useful" than the multiplicative identity?

>> I'm not aware of any mathematical justification for such a conclusion.

>>

>> Going to your original example, I should add: other languages provide a

>> version of `reduce` that doesn't require an initial result (for
instance,

>> JavaScript). In JavaScript, `[1, 2, 3].reduce((a, b) => a + b)` uses the

>> element at array index 0 as the initial result, and the accumulator

>> function is invoked starting with the element at array index 1. This is

>> precisely equivalent to having `reduce` use the additive identity as the

>> default initial result when + is the accumulator function and the

>> multiplicative identity when * is the accumulator function (with the

>> accumulator function being invoked starting with the element at array
index

>> 0). It does not require a DefaultConstructible protocol. What more

>> ergonomic solution could be implemented using a monoidic wrapper type?

>>

>>

>>

> _______________________________________________

> swift-evolution mailing list

> swift-evolution@swift.org

> https://lists.swift.org/mailman/listinfo/swift-evolution

>

--

-Dave

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

Yep, exactly, a to something very common. In practice users have rarely to
conform to other stuff, also these protocols are not a part of standard
library. Seriously, if we continue thinking like this we should as well get
rid of implicit constructors too.

···

On Mon, 26 Dec 2016 at 11:31 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:55 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Ok, an example:

func myFactory<T: DefaultConstructable>(c:T.Type) -> T {
let t = T()

if let ini = t as? Initializable {
ini.initialize(self)
}

if let co = t as? ContextAware {
co.setContext(context)
}

//etc

return t
}

So, users will need to conform to Initializable, ContextAware, etc. But
you insist on compiler magic for DefaultConstructible?

On Mon, 26 Dec 2016 at 11:19 Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used independently
of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol? Wouldn't
the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

>> https://vapor.github.io/documentation/fluent/model.html

>> https://github.com/blitzagency/amigo-swift

>>

>>

>> In general I think the best showcase is generic factories.

>>

>> On Mon, 26 Dec 2016 at 9:02 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 10:18 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Usually it's a generic function that needs to return a value from some

>> other function or a default value (zero) in a case of some conditions.

>> Optional value is an arguable solution in quite some scenarios. Afaik,

>> sometimes it can be used for optional resolution.

>>

>>

>> Right, I'd agree that Optional is the idiomatic way to do it. Afaict,

>> there's not much you can do with a default value that you couldn't with

>> nil, unless you have some guarantee as to _what_ that default is;
however,

>> I'd expect that in every case that you can rely on a guarantee about a

>> default value which would be more useful than nil, it's going to require

>> more specific knowledge of your type than an all-encompassing

>> `DefaultConstructible` can provide.

>>

>> Also, generic factories. Widely used in ORM solutions.

>>

>>

>> Can you elaborate on this? Why is Optional not a solution here?

>>

>>

>> As mentioned above, algorythmical stuff that requires Zero.

>>

>>

>> I'm still not convinced there exist credible use cases that need to be

>> generic over both collections and floating point, for instance. In
fact, in

>> my experience, there are few math-heavy algorithms where one can ignore

>> even the distinction between integers and binary floating point. By the

>> time you get down to matrix math, you start to run into difficulties
that

>> require separate implementations for Float and Double.

>>

>> On Mon, 26 Dec 2016 at 8:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> Can you give some examples of what you used this approach to do?

>>

>>

>> On Sun, Dec 25, 2016 at 9:49 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> +1 to this approach. I remember I had to create it on my own for my

>> projects. Would be nice to have it out of the box.

>>

>> On Mon, 26 Dec 2016 at 8:11 Adam Nemecek via swift-evolution < > > > >> swift-evolution@swift.org> wrote:

>>

>> > Yes, those particular types have initializers that take no arguments.

>> That does not address my question. You merely restated your initial

>> observation that many types in Swift have implemented `init()`.

>>

>> Right, it's an empirical argument.

>>

>> > I didn't think the value returned by `init()` was regarded as any sort

>> of zero--or even any sort of "default." In fact, some types in
Foundation

>> have a static property called `default` distinct from `init()`.

>>

>> Let's not talk about those then. This would not apply to every single
type

>> in existence, as I've stated previously.

>>

>> > It gives you something different every time. How can this be squared

>> with your stated motivation regarding concepts of zero and concepts of

>> equality?

>>

>> Due to the fact that it's a resource, not a value. As I've stated above,

>> not all of this applies to types that are more resource-like.

>>

>> > Or, it's what you get because that's the most trivial possible string.

>> Quite simply, I do not think the designer of most types that implement

>> `init()` have paused to wonder whether the value that you get is the

>> identity element associated with the most useful and prominent operation

>> that can be performed on that type. I certainly never have.

>>

>> This is an appeal to tradition.

>>

>> > The statement I wrote was in JavaScript, so I'm not sure what you mean

>> by returning an optional. `[].reduce((a, b) => a + b)` results in an

>> error in JavaScript. In Swift, such a function may also be implemented
with

>> a precondition that the array is not empty and would not return an
optional.

>>

>> I was talking about their analogous swift implementations.

>>

>> > Can you give an example of an algorithm dealing with tensors where you

>> would use a `DefaultConstructible` generic over all types that have

>> `init()`, as opposed to working with the existing `Integer`,

>> `FloatingPoint`, and other numerical protocols?

>>

>> If it's implemented as either nested collections or numbers.

>>

>>

>>

>> On Sun, Dec 25, 2016 at 6:00 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 7:30 PM, Adam Nemecek <adamnemecek@gmail.com> > > > >> wrote:

>>

>> > Is it well settled, either in Swift or in C++/Rust/etc., that the
value

>> returned by a default initializer/constructor is regarded as an identity

>> element or zero?

>>

>> Int() == 0, String() == "" so to some extent by convention, a lot of
types

>> have a default value as is.

>>

>>

>> Yes, those particular types have initializers that take no arguments.
That

>> does not address my question. You merely restated your initial
observation

>> that many types in Swift have implemented `init()`.

>>

>> I didn't think the value returned by `init()` was regarded as any sort
of

>> zero--or even any sort of "default." In fact, some types in Foundation
have

>> a static property called `default` distinct from `init()`. In Rust, the

>> Default trait requires a function called `default()`, which is
documented

>> as being useful when you want "some kind of default value, and don't

>> particularly care what it is."

>>

>> I was asking whether there's some understanding, of which I've been

>> unaware, that the result of `init()` (or the equivalent in other
languages)

>> is expected to be some sort of zero or an identity element. I'm not
aware

>> of any evidence to that effect. Are you?

>>

>> > Is the thread that I get by writing `let t = Thread()` some kind of
zero

>> in any reasonable sense of the word?

>>

>> DefaultConstructibility makes less sense for types that represent some

>> sort of resource but make sense for things that are values. But even in

>> this case, Thread() gives you a default value for example if you are

>> working with a resizable collection of threads.

>>

>>

>> It gives you something different every time. How can this be squared
with

>> your stated motivation regarding concepts of zero and concepts of
equality?

>>

>> A better question is why does thread currently implement a default

>> constructor?

>>

>>

>> It's an initializer that takes no arguments, because none are needed
for a

>> new thread. How else would you write it?

>>

>> > Do you mean to argue that for an integer the additive identity should
be

>> considered "more prominent and useful" than the multiplicative identity?

>> I'm not aware of any mathematical justification for such a conclusion.

>>

>> I do. The justification is that if I call the default constructor of Int

>> currently, I get the value of 0.

>>

>>

>> This is backwards. Why do you believe that the value you obtain from

>> `init()` is intended to be an identity element at all, let alone the
most

>> important one? (It's also circular reasoning. Since `init()` only ever

>> gives you one value at a time, by your reasoning it demonstrates that
every

>> type must have one "more prominent and useful" identity, which is
begging

>> the question.)

>>

>> Which means that the binary operation must be addition.

>>

>>

>> Based on the value of `Int.init()`, you conclude that addition of
integers

>> is a "more prominent and useful" operation than multiplication? Again,
this

>> is backwards. Rather, we know that each numerical type belongs to
multiple

>> ring algebras; there is no basis for reckoning any as "more useful."
Since

>> `init()` can only ever give us one value at a time, we know that
`init()`

>> cannot give a value that is a meaningful default with respect to any

>> particular operation.

>>

>> If I call String() I get "" which is the identity of the + String

>> operation.

>>

>>

>> Or, it's what you get because that's the most trivial possible string.

>> Quite simply, I do not think the designer of most types that implement

>> `init()` have paused to wonder whether the value that you get is the

>> identity element associated with the most useful and prominent operation

>> that can be performed on that type. I certainly never have.

>>

>> > Going to your original example, I should add: other languages provide
a

>> version of `reduce` that doesn't require an initial result (for
instance,

>> JavaScript). In JavaScript, `[1, 2, 3].reduce((a, b) => a + b)` uses the

>> element at array index 0 as the initial result, and the accumulator

>> function is invoked starting with the element at array index 1. This is

>> precisely equivalent to having `reduce` use the additive identity as the

>> default initial result when + is the accumulator function and the

>> multiplicative identity when * is the accumulator function (with the

>> accumulator function being invoked starting with the element at array
index

>> 0). It does not require a DefaultConstructible protocol. What more

>> ergonomic solution could be implemented using a monoidic wrapper type?

>>

>> These two will have different signatures. The reduce you describe
returns

>> an optional,

>>

>>

>> The statement I wrote was in JavaScript, so I'm not sure what you mean
by

>> returning an optional. `[].reduce((a, b) => a + b)` results in an error

>> in JavaScript. In Swift, such a function may also be implemented with a

>> precondition that the array is not empty and would not return an
optional.

>>

>> the other one would returns the default value.

>>

>>

>> In what scenario would you prefer to propagate a default after reducing
a

>> potential empty collection _without supplying an explicit default_ for
that

>> operation? This would certainly violate the Swift convention of not

>> defaulting to zero and, I suspect, most users of Swift would not regard

>> that as ergonomic at all.

>>

>>

>> Fundamentally the default constructibles are useful in numerical

>> computations e..g. dealing with tensors.

>>

>>

>> Can you give an example of an algorithm dealing with tensors where you

>> would use a `DefaultConstructible` generic over all types that have

>> `init()`, as opposed to working with the existing `Integer`,

>> `FloatingPoint`, and other numerical protocols? (I should also add,
FWIW, I

>> have never seen a generic algorithm written for integers or FP types
that

>> has preferred the use of `T()` over `0`.)

>>

>>

>> On Sun, Dec 25, 2016 at 3:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 5:27 PM, Adam Nemecek <adamnemecek@gmail.com> > > > >> wrote:

>>

>> > *Which* APIs become more ergonomic?

>>

>> I'll get back to this question in a second if I may. This would be a

>> longer discussion and I first want to make sure that before we get into
the

>> details that there is a possibility of this being introduced (I'm
asking if

>> violating the no zero defaults is more important than slightly more

>> ergonomic APIs). But to give a broad answer I think that the concept of
a

>> zero is closely related to the concept of equality (and all the things
that

>> build up on equality such as comparability and negation).

>>

>> > 1) How does this square with Swift’s general philosophy to not default

>> initialize values to “zero”?

>>

>> I actually wasn't aware of this philosophy. Despite this philosophy,
look

>> at how many types actually currently implement a default constructor.

>>

>>

>> (Not a rhetorical question:) Is it well settled, either in Swift or in

>> C++/Rust/etc., that the value returned by a default
initializer/constructor

>> is regarded as an identity element or zero? Is the thread that I get by

>> writing `let t = Thread()` some kind of zero in any reasonable sense of
the

>> word?

>>

>>

>> Also can I ask what's the motivation behind this philosophy?

>> I think that in Swift, default constructibility makes complete sense for

>> (most?) structs, maybe less so for classes.

>>

>> > 2) To your original example, it isn’t immediately clear to me that

>> reduce should choose a default identity. Some types (e.g. integers and
FP)

>> belong to multiple different ring algebras, and therefore have different

>> identity values that correspond to the relevant binary operations.

>>

>> This is a good point that I've considered as well but felt that for the

>> most part, there is one particular identity and associated operation
that

>> is more prominent and useful than others. Furthermore, modeling
different

>> algebras isn't mutually exclusive with writing generic algorithms that
rely

>> on this protocol, you can always introduce some monoidic wrapper type
that

>> defines the more appropriate default value and operation.

>>

>>

>> Do you mean to argue that for an integer the additive identity should be

>> considered "more prominent and useful" than the multiplicative identity?

>> I'm not aware of any mathematical justification for such a conclusion.

>>

>> Going to your original example, I should add: other languages provide a

I'm giving a wider range, which is about ANY factory pattern related stuff.
Doesn't look to be narrow to me.

···

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used independently
of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol? Wouldn't
the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

>> https://vapor.github.io/documentation/fluent/model.html

>> https://github.com/blitzagency/amigo-swift

>>

>>

>> In general I think the best showcase is generic factories.

>>

>> On Mon, 26 Dec 2016 at 9:02 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 10:18 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Usually it's a generic function that needs to return a value from some

>> other function or a default value (zero) in a case of some conditions.

>> Optional value is an arguable solution in quite some scenarios. Afaik,

>> sometimes it can be used for optional resolution.

>>

>>

>> Right, I'd agree that Optional is the idiomatic way to do it. Afaict,

>> there's not much you can do with a default value that you couldn't with

>> nil, unless you have some guarantee as to _what_ that default is;
however,

>> I'd expect that in every case that you can rely on a guarantee about a

>> default value which would be more useful than nil, it's going to require

>> more specific knowledge of your type than an all-encompassing

>> `DefaultConstructible` can provide.

>>

>> Also, generic factories. Widely used in ORM solutions.

>>

>>

>> Can you elaborate on this? Why is Optional not a solution here?

>>

>>

>> As mentioned above, algorythmical stuff that requires Zero.

>>

>>

>> I'm still not convinced there exist credible use cases that need to be

>> generic over both collections and floating point, for instance. In
fact, in

>> my experience, there are few math-heavy algorithms where one can ignore

>> even the distinction between integers and binary floating point. By the

>> time you get down to matrix math, you start to run into difficulties
that

>> require separate implementations for Float and Double.

>>

>> On Mon, 26 Dec 2016 at 8:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> Can you give some examples of what you used this approach to do?

>>

>>

>> On Sun, Dec 25, 2016 at 9:49 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> +1 to this approach. I remember I had to create it on my own for my

>> projects. Would be nice to have it out of the box.

>>

>> On Mon, 26 Dec 2016 at 8:11 Adam Nemecek via swift-evolution < > > > >> swift-evolution@swift.org> wrote:

>>

>> > Yes, those particular types have initializers that take no arguments.

>> That does not address my question. You merely restated your initial

>> observation that many types in Swift have implemented `init()`.

>>

>> Right, it's an empirical argument.

>>

>> > I didn't think the value returned by `init()` was regarded as any sort

>> of zero--or even any sort of "default." In fact, some types in
Foundation

>> have a static property called `default` distinct from `init()`.

>>

>> Let's not talk about those then. This would not apply to every single
type

>> in existence, as I've stated previously.

>>

>> > It gives you something different every time. How can this be squared

>> with your stated motivation regarding concepts of zero and concepts of

>> equality?

>>

>> Due to the fact that it's a resource, not a value. As I've stated above,

>> not all of this applies to types that are more resource-like.

>>

>> > Or, it's what you get because that's the most trivial possible string.

>> Quite simply, I do not think the designer of most types that implement

>> `init()` have paused to wonder whether the value that you get is the

>> identity element associated with the most useful and prominent operation

>> that can be performed on that type. I certainly never have.

>>

>> This is an appeal to tradition.

>>

>> > The statement I wrote was in JavaScript, so I'm not sure what you mean

>> by returning an optional. `[].reduce((a, b) => a + b)` results in an

>> error in JavaScript. In Swift, such a function may also be implemented
with

>> a precondition that the array is not empty and would not return an
optional.

>>

>> I was talking about their analogous swift implementations.

>>

>> > Can you give an example of an algorithm dealing with tensors where you

>> would use a `DefaultConstructible` generic over all types that have

>> `init()`, as opposed to working with the existing `Integer`,

>> `FloatingPoint`, and other numerical protocols?

>>

>> If it's implemented as either nested collections or numbers.

>>

>>

>>

>> On Sun, Dec 25, 2016 at 6:00 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 7:30 PM, Adam Nemecek <adamnemecek@gmail.com> > > > >> wrote:

>>

>> > Is it well settled, either in Swift or in C++/Rust/etc., that the
value

>> returned by a default initializer/constructor is regarded as an identity

>> element or zero?

>>

>> Int() == 0, String() == "" so to some extent by convention, a lot of
types

>> have a default value as is.

>>

>>

>> Yes, those particular types have initializers that take no arguments.
That

>> does not address my question. You merely restated your initial
observation

>> that many types in Swift have implemented `init()`.

>>

>> I didn't think the value returned by `init()` was regarded as any sort
of

>> zero--or even any sort of "default." In fact, some types in Foundation
have

>> a static property called `default` distinct from `init()`. In Rust, the

>> Default trait requires a function called `default()`, which is
documented

>> as being useful when you want "some kind of default value, and don't

>> particularly care what it is."

>>

>> I was asking whether there's some understanding, of which I've been

>> unaware, that the result of `init()` (or the equivalent in other
languages)

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

···

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used independently
of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol? Wouldn't
the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

>> https://vapor.github.io/documentation/fluent/model.html

>> https://github.com/blitzagency/amigo-swift

>>

>>

>> In general I think the best showcase is generic factories.

>>

>> On Mon, 26 Dec 2016 at 9:02 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 10:18 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Usually it's a generic function that needs to return a value from some

>> other function or a default value (zero) in a case of some conditions.

>> Optional value is an arguable solution in quite some scenarios. Afaik,

>> sometimes it can be used for optional resolution.

>>

>>

>> Right, I'd agree that Optional is the idiomatic way to do it. Afaict,

>> there's not much you can do with a default value that you couldn't with

>> nil, unless you have some guarantee as to _what_ that default is;
however,

>> I'd expect that in every case that you can rely on a guarantee about a

>> default value which would be more useful than nil, it's going to require

>> more specific knowledge of your type than an all-encompassing

>> `DefaultConstructible` can provide.

>>

>> Also, generic factories. Widely used in ORM solutions.

>>

>>

>> Can you elaborate on this? Why is Optional not a solution here?

>>

>>

>> As mentioned above, algorythmical stuff that requires Zero.

>>

>>

>> I'm still not convinced there exist credible use cases that need to be

>> generic over both collections and floating point, for instance. In
fact, in

>> my experience, there are few math-heavy algorithms where one can ignore

Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY
conformed by all classes.

What you say is just another approach to the same issue and we can argue
for eternity. However, I am very positive with syntactic sugar and this one
falls exactly to sugar category. Make people lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc (proven
by time, btw) on board sounds very appealing to me. I wish to see Swift a
very diverse ecosystem and this Pitch serves exactly this goal.

Let's just see if it gets any more positive votes.

···

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory
pattern" and just wanted to point out that at least some of those patterns
seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type
implement `init()`?" is properly a reflection question and not a protocol
conformance question: the answer provides no semantic guarantees whatsoever
about the value that you get from `init()`, and in your use case you do not
care and simply want to invoke the initializer and return what you get from
it. Now, in a perfect world where the reflection facilities that Swift
provided were essentially free of performance cost, would you object to
that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious
that Obj-C bridging is non-negotiable for Swift, and of course a bridged
type is all sorts of different under the hood from a native type. I'm going
to take a wild guess that no other use case would pass that high bar for
magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used independently
of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol? Wouldn't
the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

I totally agree Swift is an opinionated language and it's good.

Also I have been thinking of DefaultConstructable vs reflection for generic
factories and I would prefer to stick to the protocol as it gives compile
time type safety check. With reflection the only way is to through an
exception if there is no init. So again +1 pro to DefaultConstructable.

···

On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY
conformed by all classes.

What you say is just another approach to the same issue and we can argue
for eternity. However, I am very positive with syntactic sugar and this one
falls exactly to sugar category. Make people lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc (proven
by time, btw) on board sounds very appealing to me. I wish to see Swift a
very diverse ecosystem and this Pitch serves exactly this goal.

Yes, we should let others chime in on this issue. I will just end by
saying that I've always appreciated how the core team has been very careful
and thoughtful about certain precepts, and how they've stuck to the idea
that Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought put into
semantic meaning. The notion that protocols should carry semantics has been
adhered to very strictly. This is why I think this proposal does do harm,
because it explicitly rejects that very important idea, one that can only
be upheld by people and not compilers.

(Another semantic distinction observed in Swift is that a boolean value
has semantic meaning and is not just a bit; this is why, for instance, the
FloatingPoint protocols define an `enum FloatingPointSign { case plus,
minus }`--because floating point sign has different _semantics_ from a
Bool.)

Let's just see if it gets any more positive votes.

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory
pattern" and just wanted to point out that at least some of those patterns
seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type
implement `init()`?" is properly a reflection question and not a protocol
conformance question: the answer provides no semantic guarantees whatsoever
about the value that you get from `init()`, and in your use case you do not
care and simply want to invoke the initializer and return what you get from
it. Now, in a perfect world where the reflection facilities that Swift
provided were essentially free of performance cost, would you object to
that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious
that Obj-C bridging is non-negotiable for Swift, and of course a bridged
type is all sorts of different under the hood from a native type. I'm going
to take a wild guess that no other use case would pass that high bar for
magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used independently
of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

It's not a matter of probability, but rather of certainty. Please.

···

On Mon, 26 Dec 2016 at 12:56 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I totally agree Swift is an opinionated language and it's good.

Also I have been thinking of DefaultConstructable vs reflection for
generic factories and I would prefer to stick to the protocol as it gives
compile time type safety check. With reflection the only way is to through
an exception if there is no init. So again +1 pro to DefaultConstructable.

Well, you can't argue both ways. Either so many types implement `init()`
that it is unusually onerous to type, in which case you will gain nearly
nothing from compile-time checks, or not so many types implement `init()`,
and you can conform those types to a protocol by yourself :slight_smile:

On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY
conformed by all classes.

What you say is just another approach to the same issue and we can argue
for eternity. However, I am very positive with syntactic sugar and this one
falls exactly to sugar category. Make people lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc (proven
by time, btw) on board sounds very appealing to me. I wish to see Swift a
very diverse ecosystem and this Pitch serves exactly this goal.

Yes, we should let others chime in on this issue. I will just end by
saying that I've always appreciated how the core team has been very careful
and thoughtful about certain precepts, and how they've stuck to the idea
that Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought put into
semantic meaning. The notion that protocols should carry semantics has been
adhered to very strictly. This is why I think this proposal does do harm,
because it explicitly rejects that very important idea, one that can only
be upheld by people and not compilers.

(Another semantic distinction observed in Swift is that a boolean value
has semantic meaning and is not just a bit; this is why, for instance, the
FloatingPoint protocols define an `enum FloatingPointSign { case plus,
minus }`--because floating point sign has different _semantics_ from a
Bool.)

Let's just see if it gets any more positive votes.

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory
pattern" and just wanted to point out that at least some of those patterns
seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type
implement `init()`?" is properly a reflection question and not a protocol
conformance question: the answer provides no semantic guarantees whatsoever
about the value that you get from `init()`, and in your use case you do not
care and simply want to invoke the initializer and return what you get from
it. Now, in a perfect world where the reflection facilities that Swift
provided were essentially free of performance cost, would you object to
that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious
that Obj-C bridging is non-negotiable for Swift, and of course a bridged
type is all sorts of different under the hood from a native type. I'm going
to take a wild guess that no other use case would pass that high bar for
magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

Ok, an example:

func myFactory<T: DefaultConstructable>(c:T.Type) -> T {
let t = T()

if let ini = t as? Initializable {
ini.initialize(self)
}

if let co = t as? ContextAware {
co.setContext(context)
}

//etc

return t
}

So, users will need to conform to Initializable, ContextAware, etc. But you
insist on compiler magic for DefaultConstructible?

···

On Mon, Dec 26, 2016 at 12:55 AM, Daniel Leping <daniel@crossroadlabs.xyz> wrote:

On Mon, 26 Dec 2016 at 11:19 Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < >> swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < >> swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used
independently of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol?
Wouldn't the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol
or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

>> https://vapor.github.io/documentation/fluent/model.html

>> https://github.com/blitzagency/amigo-swift

>>

>>

>> In general I think the best showcase is generic factories.

>>

>> On Mon, 26 Dec 2016 at 9:02 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 10:18 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Usually it's a generic function that needs to return a value from some

>> other function or a default value (zero) in a case of some conditions.

>> Optional value is an arguable solution in quite some scenarios. Afaik,

>> sometimes it can be used for optional resolution.

>>

>>

>> Right, I'd agree that Optional is the idiomatic way to do it. Afaict,

>> there's not much you can do with a default value that you couldn't with

>> nil, unless you have some guarantee as to _what_ that default is;
however,

>> I'd expect that in every case that you can rely on a guarantee about a

>> default value which would be more useful than nil, it's going to
require

>> more specific knowledge of your type than an all-encompassing

>> `DefaultConstructible` can provide.

>>

>> Also, generic factories. Widely used in ORM solutions.

>>

>>

>> Can you elaborate on this? Why is Optional not a solution here?

>>

>>

>> As mentioned above, algorythmical stuff that requires Zero.

>>

>>

>> I'm still not convinced there exist credible use cases that need to be

>> generic over both collections and floating point, for instance. In
fact, in

>> my experience, there are few math-heavy algorithms where one can ignore

>> even the distinction between integers and binary floating point. By the

>> time you get down to matrix math, you start to run into difficulties
that

>> require separate implementations for Float and Double.

>>

>> On Mon, 26 Dec 2016 at 8:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> Can you give some examples of what you used this approach to do?

>>

>>

>> On Sun, Dec 25, 2016 at 9:49 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> +1 to this approach. I remember I had to create it on my own for my

>> projects. Would be nice to have it out of the box.

>>

>> On Mon, 26 Dec 2016 at 8:11 Adam Nemecek via swift-evolution < >> >> >> >> swift-evolution@swift.org> wrote:

>>

>> > Yes, those particular types have initializers that take no arguments.

>> That does not address my question. You merely restated your initial

>> observation that many types in Swift have implemented `init()`.

>>

>> Right, it's an empirical argument.

>>

>> > I didn't think the value returned by `init()` was regarded as any
sort

>> of zero--or even any sort of "default." In fact, some types in
Foundation

>> have a static property called `default` distinct from `init()`.

>>

>> Let's not talk about those then. This would not apply to every single
type

>> in existence, as I've stated previously.

>>

>> > It gives you something different every time. How can this be squared

>> with your stated motivation regarding concepts of zero and concepts of

>> equality?

>>

>> Due to the fact that it's a resource, not a value. As I've stated
above,

>> not all of this applies to types that are more resource-like.

>>

>> > Or, it's what you get because that's the most trivial possible
string.

>> Quite simply, I do not think the designer of most types that implement

>> `init()` have paused to wonder whether the value that you get is the

>> identity element associated with the most useful and prominent
operation

>> that can be performed on that type. I certainly never have.

>>

>> This is an appeal to tradition.

>>

>> > The statement I wrote was in JavaScript, so I'm not sure what you
mean

>> by returning an optional. `[].reduce((a, b) => a + b)` results in an

>> error in JavaScript. In Swift, such a function may also be implemented
with

>> a precondition that the array is not empty and would not return an
optional.

>>

>> I was talking about their analogous swift implementations.

>>

>> > Can you give an example of an algorithm dealing with tensors where
you

>> would use a `DefaultConstructible` generic over all types that have

>> `init()`, as opposed to working with the existing `Integer`,

>> `FloatingPoint`, and other numerical protocols?

>>

>> If it's implemented as either nested collections or numbers.

>>

>>

>>

>> On Sun, Dec 25, 2016 at 6:00 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >> wrote:

>>

>> On Sun, Dec 25, 2016 at 7:30 PM, Adam Nemecek <adamnemecek@gmail.com> >> >> >> >> wrote:

>>

>> > Is it well settled, either in Swift or in C++/Rust/etc., that the
value

>> returned by a default initializer/constructor is regarded as an
identity

>> element or zero?

>>

>> Int() == 0, String() == "" so to some extent by convention, a lot of
types

>> have a default value as is.

>>

>>

>> Yes, those particular types have initializers that take no arguments.
That

>> does not address my question. You merely restated your initial
observation

>> that many types in Swift have implemented `init()`.

>>

>> I didn't think the value returned by `init()` was regarded as any sort
of

>> zero--or even any sort of "default." In fact, some types in Foundation
have

>> a static property called `default` distinct from `init()`. In Rust, the

>> Default trait requires a function called `default()`, which is
documented

>> as being useful when you want "some kind of default value, and don't

>> particularly care what it is."

>>

>> I was asking whether there's some understanding, of which I've been

>> unaware, that the result of `init()` (or the equivalent in other
languages)

>> is expected to be some sort of zero or an identity element. I'm not
aware

>> of any evidence to that effect. Are you?

>>

>> > Is the thread that I get by writing `let t = Thread()` some kind of
zero

>> in any reasonable sense of the word?

>>

>> DefaultConstructibility makes less sense for types that represent some

>> sort of resource but make sense for things that are values. But even in

>> this case, Thread() gives you a default value for example if you are

>> working with a resizable collection of threads.

>>

>>

>> It gives you something different every time. How can this be squared
with

>> your stated motivation regarding concepts of zero and concepts of
equality?

>>

>> A better question is why does thread currently implement a default

>> constructor?

>>

>>

>> It's an initializer that takes no arguments, because none are needed
for a

>> new thread. How else would you write it?

>>

>> > Do you mean to argue that for an integer the additive identity
should be

>> considered "more prominent and useful" than the multiplicative
identity?

>> I'm not aware of any mathematical justification for such a conclusion.

>>

>> I do. The justification is that if I call the default constructor of
Int

>> currently, I get the value of 0.

>>

>>

>> This is backwards. Why do you believe that the value you obtain from

>> `init()` is intended to be an identity element at all, let alone the
most

>> important one? (It's also circular reasoning. Since `init()` only ever

>> gives you one value at a time, by your reasoning it demonstrates that
every

>> type must have one "more prominent and useful" identity, which is
begging

>> the question.)

>>

>> Which means that the binary operation must be addition.

>>

>>

>> Based on the value of `Int.init()`, you conclude that addition of
integers

>> is a "more prominent and useful" operation than multiplication? Again,
this

>> is backwards. Rather, we know that each numerical type belongs to
multiple

>> ring algebras; there is no basis for reckoning any as "more useful."
Since

>> `init()` can only ever give us one value at a time, we know that
`init()`

>> cannot give a value that is a meaningful default with respect to any

>> particular operation.

>>

>> If I call String() I get "" which is the identity of the + String

>> operation.

>>

>>

>> Or, it's what you get because that's the most trivial possible string.

>> Quite simply, I do not think the designer of most types that implement

>> `init()` have paused to wonder whether the value that you get is the

>> identity element associated with the most useful and prominent
operation

>> that can be performed on that type. I certainly never have.

>>

>> > Going to your original example, I should add: other languages
provide a

>> version of `reduce` that doesn't require an initial result (for
instance,

>> JavaScript). In JavaScript, `[1, 2, 3].reduce((a, b) => a + b)` uses
the

>> element at array index 0 as the initial result, and the accumulator

>> function is invoked starting with the element at array index 1. This is

>> precisely equivalent to having `reduce` use the additive identity as
the

>> default initial result when + is the accumulator function and the

>> multiplicative identity when * is the accumulator function (with the

>> accumulator function being invoked starting with the element at array
index

>> 0). It does not require a DefaultConstructible protocol. What more

>> ergonomic solution could be implemented using a monoidic wrapper type?

>>

>> These two will have different signatures. The reduce you describe
returns

>> an optional,

>>

>>

>> The statement I wrote was in JavaScript, so I'm not sure what you mean
by

>> returning an optional. `[].reduce((a, b) => a + b)` results in an error

>> in JavaScript. In Swift, such a function may also be implemented with a

>> precondition that the array is not empty and would not return an
optional.

>>

>> the other one would returns the default value.

>>

>>

>> In what scenario would you prefer to propagate a default after
reducing a

>> potential empty collection _without supplying an explicit default_ for
that

>> operation? This would certainly violate the Swift convention of not

>> defaulting to zero and, I suspect, most users of Swift would not regard

>> that as ergonomic at all.

>>

>>

>> Fundamentally the default constructibles are useful in numerical

>> computations e..g. dealing with tensors.

>>

>>

>> Can you give an example of an algorithm dealing with tensors where you

>> would use a `DefaultConstructible` generic over all types that have

>> `init()`, as opposed to working with the existing `Integer`,

>> `FloatingPoint`, and other numerical protocols? (I should also add,
FWIW, I

>> have never seen a generic algorithm written for integers or FP types
that

>> has preferred the use of `T()` over `0`.)

>>

>>

>> On Sun, Dec 25, 2016 at 3:30 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >> wrote:

>>

>> On Sun, Dec 25, 2016 at 5:27 PM, Adam Nemecek <adamnemecek@gmail.com> >> >> >> >> wrote:

>>

>> > *Which* APIs become more ergonomic?

>>

>> I'll get back to this question in a second if I may. This would be a

>> longer discussion and I first want to make sure that before we get
into the

>> details that there is a possibility of this being introduced (I'm
asking if

>> violating the no zero defaults is more important than slightly more

>> ergonomic APIs). But to give a broad answer I think that the concept
of a

>> zero is closely related to the concept of equality (and all the things
that

>> build up on equality such as comparability and negation).

>>

>> > 1) How does this square with Swift’s general philosophy to not
default

>> initialize values to “zero”?

>>

>> I actually wasn't aware of this philosophy. Despite this philosophy,
look

>> at how many types actually currently implement a default constructor.

>>

>>

>> (Not a rhetorical question:) Is it well settled, either in Swift or in

>> C++/Rust/etc., that the value returned by a default
initializer/constructor

>> is regarded as an identity element or zero? Is the thread that I get by

>> writing `let t = Thread()` some kind of zero in any reasonable sense
of the

>> word?

>>

>>

>> Also can I ask what's the motivation behind this philosophy?

>> I think that in Swift, default constructibility makes complete sense
for

>> (most?) structs, maybe less so for classes.

>>

>> > 2) To your original example, it isn’t immediately clear to me that

>> reduce should choose a default identity. Some types (e.g. integers
and FP)

>> belong to multiple different ring algebras, and therefore have
different

>> identity values that correspond to the relevant binary operations.

>>

>> This is a good point that I've considered as well but felt that for the

>> most part, there is one particular identity and associated operation
that

>> is more prominent and useful than others. Furthermore, modeling
different

>> algebras isn't mutually exclusive with writing generic algorithms that
rely

>> on this protocol, you can always introduce some monoidic wrapper type
that

>> defines the more appropriate default value and operation.

>>

>>

>> Do you mean to argue that for an integer the additive identity should
be

>> considered "more prominent and useful" than the multiplicative
identity?

>> I'm not aware of any mathematical justification for such a conclusion.

>>

>> Going to your original example, I should add: other languages provide a

>> version of `reduce` that doesn't require an initial result (for
instance,

>> JavaScript). In JavaScript, `[1, 2, 3].reduce((a, b) => a + b)` uses
the

>> element at array index 0 as the initial result, and the accumulator

>> function is invoked starting with the element at array index 1. This is

>> precisely equivalent to having `reduce` use the additive identity as
the

>> default initial result when + is the accumulator function and the

>> multiplicative identity when * is the accumulator function (with the

>> accumulator function being invoked starting with the element at array
index

>> 0). It does not require a DefaultConstructible protocol. What more

>> ergonomic solution could be implemented using a monoidic wrapper type?

>>

>>

>>

> _______________________________________________

> swift-evolution mailing list

> swift-evolution@swift.org

> https://lists.swift.org/mailman/listinfo/swift-evolution

>

--

-Dave

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of the
stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

···

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> wrote:

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < >> swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < >> swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used
independently of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol?
Wouldn't the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol
or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

>> https://vapor.github.io/documentation/fluent/model.html

>> https://github.com/blitzagency/amigo-swift

>>

>>

>> In general I think the best showcase is generic factories.

>>

>> On Mon, 26 Dec 2016 at 9:02 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 10:18 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Usually it's a generic function that needs to return a value from some

>> other function or a default value (zero) in a case of some conditions.

>> Optional value is an arguable solution in quite some scenarios. Afaik,

>> sometimes it can be used for optional resolution.

>>

>>

>> Right, I'd agree that Optional is the idiomatic way to do it. Afaict,

>> there's not much you can do with a default value that you couldn't with

>> nil, unless you have some guarantee as to _what_ that default is;
however,

>> I'd expect that in every case that you can rely on a guarantee about a

>> default value which would be more useful than nil, it's going to
require

>> more specific knowledge of your type than an all-encompassing

>> `DefaultConstructible` can provide.

>>

>> Also, generic factories. Widely used in ORM solutions.

>>

>>

>> Can you elaborate on this? Why is Optional not a solution here?

>>

>>

>> As mentioned above, algorythmical stuff that requires Zero.

>>

>>

>> I'm still not convinced there exist credible use cases that need to be

>> generic over both collections and floating point, for instance. In
fact, in

>> my experience, there are few math-heavy algorithms where one can ignore

>> even the distinction between integers and binary floating point. By the

>> time you get down to matrix math, you start to run into difficulties
that

>> require separate implementations for Float and Double.

>>

>> On Mon, 26 Dec 2016 at 8:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> Can you give some examples of what you used this approach to do?

>>

>>

>> On Sun, Dec 25, 2016 at 9:49 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> +1 to this approach. I remember I had to create it on my own for my

>> projects. Would be nice to have it out of the box.

>>

>> On Mon, 26 Dec 2016 at 8:11 Adam Nemecek via swift-evolution < >> >> >> >> swift-evolution@swift.org> wrote:

>>

>> > Yes, those particular types have initializers that take no arguments.

>> That does not address my question. You merely restated your initial

>> observation that many types in Swift have implemented `init()`.

>>

>> Right, it's an empirical argument.

>>

>> > I didn't think the value returned by `init()` was regarded as any
sort

>> of zero--or even any sort of "default." In fact, some types in
Foundation

>> have a static property called `default` distinct from `init()`.

>>

>> Let's not talk about those then. This would not apply to every single
type

>> in existence, as I've stated previously.

>>

>> > It gives you something different every time. How can this be squared

>> with your stated motivation regarding concepts of zero and concepts of

>> equality?

>>

>> Due to the fact that it's a resource, not a value. As I've stated
above,

>> not all of this applies to types that are more resource-like.

>>

>> > Or, it's what you get because that's the most trivial possible
string.

>> Quite simply, I do not think the designer of most types that implement

>> `init()` have paused to wonder whether the value that you get is the

>> identity element associated with the most useful and prominent
operation

>> that can be performed on that type. I certainly never have.

>>

>> This is an appeal to tradition.

>>

>> > The statement I wrote was in JavaScript, so I'm not sure what you
mean

>> by returning an optional. `[].reduce((a, b) => a + b)` results in an

>> error in JavaScript. In Swift, such a function may also be implemented
with

>> a precondition that the array is not empty and would not return an
optional.

>>

>> I was talking about their analogous swift implementations.

>>

>> > Can you give an example of an algorithm dealing with tensors where
you

>> would use a `DefaultConstructible` generic over all types that have

>> `init()`, as opposed to working with the existing `Integer`,

>> `FloatingPoint`, and other numerical protocols?

>>

>> If it's implemented as either nested collections or numbers.

>>

>>

>>

>> On Sun, Dec 25, 2016 at 6:00 PM, Xiaodi Wu <xiaodi.wu@gmail.com> >> wrote:

>>

>> On Sun, Dec 25, 2016 at 7:30 PM, Adam Nemecek <adamnemecek@gmail.com> >> >> >> >> wrote:

>>

>> > Is it well settled, either in Swift or in C++/Rust/etc., that the
value

>> returned by a default initializer/constructor is regarded as an
identity

>> element or zero?

>>

>> Int() == 0, String() == "" so to some extent by convention, a lot of
types

>> have a default value as is.

>>

>>

>> Yes, those particular types have initializers that take no arguments.
That

>> does not address my question. You merely restated your initial
observation

>> that many types in Swift have implemented `init()`.

>>

>> I didn't think the value returned by `init()` was regarded as any sort
of

>> zero--or even any sort of "default." In fact, some types in Foundation
have

>> a static property called `default` distinct from `init()`. In Rust, the

>> Default trait requires a function called `default()`, which is
documented

>> as being useful when you want "some kind of default value, and don't

>> particularly care what it is."

>>

>> I was asking whether there's some understanding, of which I've been

>> unaware, that the result of `init()` (or the equivalent in other
languages)

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory
pattern" and just wanted to point out that at least some of those patterns
seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type
implement `init()`?" is properly a reflection question and not a protocol
conformance question: the answer provides no semantic guarantees whatsoever
about the value that you get from `init()`, and in your use case you do not
care and simply want to invoke the initializer and return what you get from
it. Now, in a perfect world where the reflection facilities that Swift
provided were essentially free of performance cost, would you object to
that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious that
Obj-C bridging is non-negotiable for Swift, and of course a bridged type is
all sorts of different under the hood from a native type. I'm going to take
a wild guess that no other use case would pass that high bar for magic.

···

On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz> wrote:

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> >> wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < >> swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < >> swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used
independently of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol?
Wouldn't the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol
or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

>> https://vapor.github.io/documentation/fluent/model.html

>> https://github.com/blitzagency/amigo-swift

>>

>>

>> In general I think the best showcase is generic factories.

>>

>> On Mon, 26 Dec 2016 at 9:02 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>>

>> On Sun, Dec 25, 2016 at 10:18 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Usually it's a generic function that needs to return a value from some

>> other function or a default value (zero) in a case of some conditions.

>> Optional value is an arguable solution in quite some scenarios. Afaik,

>> sometimes it can be used for optional resolution.

>>

>>

>> Right, I'd agree that Optional is the idiomatic way to do it. Afaict,

>> there's not much you can do with a default value that you couldn't with

>> nil, unless you have some guarantee as to _what_ that default is;
however,

>> I'd expect that in every case that you can rely on a guarantee about a

>> default value which would be more useful than nil, it's going to
require

>> more specific knowledge of your type than an all-encompassing

>> `DefaultConstructible` can provide.

>>

>> Also, generic factories. Widely used in ORM solutions.

>>

>>

>> Can you elaborate on this? Why is Optional not a solution here?

>>

>>

>> As mentioned above, algorythmical stuff that requires Zero.

>>

>>

>> I'm still not convinced there exist credible use cases that need to be

>> generic over both collections and floating point, for instance. In
fact, in

>> my experience, there are few math-heavy algorithms where one can ignore

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory
pattern" and just wanted to point out that at least some of those patterns
seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type
implement `init()`?" is properly a reflection question and not a protocol
conformance question: the answer provides no semantic guarantees whatsoever
about the value that you get from `init()`, and in your use case you do not
care and simply want to invoke the initializer and return what you get from
it. Now, in a perfect world where the reflection facilities that Swift
provided were essentially free of performance cost, would you object to
that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious that
Obj-C bridging is non-negotiable for Swift, and of course a bridged type is
all sorts of different under the hood from a native type. I'm going to take
a wild guess that no other use case would pass that high bar for magic.

[Resent after truncating replies.]

···

On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz> wrote:

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> >> wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < >> swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < >> swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY
conformed by all classes.

What you say is just another approach to the same issue and we can argue
for eternity. However, I am very positive with syntactic sugar and this one
falls exactly to sugar category. Make people lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc (proven
by time, btw) on board sounds very appealing to me. I wish to see Swift a
very diverse ecosystem and this Pitch serves exactly this goal.

Yes, we should let others chime in on this issue. I will just end by saying
that I've always appreciated how the core team has been very careful and
thoughtful about certain precepts, and how they've stuck to the idea that
Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought put into
semantic meaning. The notion that protocols should carry semantics has been
adhered to very strictly. This is why I think this proposal does do harm,
because it explicitly rejects that very important idea, one that can only
be upheld by people and not compilers.

(Another semantic distinction observed in Swift is that a boolean value has
semantic meaning and is not just a bit; this is why, for instance, the
FloatingPoint protocols define an `enum FloatingPointSign { case plus,
minus }`--because floating point sign has different _semantics_ from a
Bool.)

Let's just see if it gets any more positive votes.

···

On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping <daniel@crossroadlabs.xyz> wrote:

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz> >> wrote:

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory
pattern" and just wanted to point out that at least some of those patterns
seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type
implement `init()`?" is properly a reflection question and not a protocol
conformance question: the answer provides no semantic guarantees whatsoever
about the value that you get from `init()`, and in your use case you do not
care and simply want to invoke the initializer and return what you get from
it. Now, in a perfect world where the reflection facilities that Swift
provided were essentially free of performance cost, would you object to
that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious
that Obj-C bridging is non-negotiable for Swift, and of course a bridged
type is all sorts of different under the hood from a native type. I'm going
to take a wild guess that no other use case would pass that high bar for
magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> >> wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < >> swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < >> swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used
independently of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

could.

> On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

>

>> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping

>> <daniel@crossroadlabs.xyz>

>> wrote:

>>

>> Ok, an example from ORM. You have an entity factory with a virtual
(read,

>> overloadable in the subclasses) method populating the properties.

>> DefaultConstructable is a great choice here. Otherwise you will have to

>> force the users of your ORM to implement a certain protocol, which you
most

>> probably would like to avoid.

>>

>>

>> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
you

>> want to avoid having your users conform to a certain protocol?
Wouldn't the

>> users of your ORM have to conform to `DefaultConstructible` then? I'm

>> looking at Swift ORMs, and all require users to conform to a protocol
or

>> inherit from a base class, typically named `Model` or similar. From a
quick

>> Google search:

>>

I totally agree Swift is an opinionated language and it's good.

Also I have been thinking of DefaultConstructable vs reflection for
generic factories and I would prefer to stick to the protocol as it gives
compile time type safety check. With reflection the only way is to through
an exception if there is no init. So again +1 pro to DefaultConstructable.

Well, you can't argue both ways. Either so many types implement `init()`
that it is unusually onerous to type, in which case you will gain nearly
nothing from compile-time checks, or not so many types implement `init()`,
and you can conform those types to a protocol by yourself :slight_smile:

···

On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping <daniel@crossroadlabs.xyz> wrote:

On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping <daniel@crossroadlabs.xyz> >> wrote:

Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY
conformed by all classes.

What you say is just another approach to the same issue and we can argue
for eternity. However, I am very positive with syntactic sugar and this one
falls exactly to sugar category. Make people lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc
(proven by time, btw) on board sounds very appealing to me. I wish to see
Swift a very diverse ecosystem and this Pitch serves exactly this goal.

Yes, we should let others chime in on this issue. I will just end by
saying that I've always appreciated how the core team has been very careful
and thoughtful about certain precepts, and how they've stuck to the idea
that Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought put
into semantic meaning. The notion that protocols should carry semantics has
been adhered to very strictly. This is why I think this proposal does do
harm, because it explicitly rejects that very important idea, one that can
only be upheld by people and not compilers.

(Another semantic distinction observed in Swift is that a boolean value
has semantic meaning and is not just a bit; this is why, for instance, the
FloatingPoint protocols define an `enum FloatingPointSign { case plus,
minus }`--because floating point sign has different _semantics_ from a
Bool.)

Let's just see if it gets any more positive votes.

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz> >> wrote:

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory
pattern" and just wanted to point out that at least some of those patterns
seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type
implement `init()`?" is properly a reflection question and not a protocol
conformance question: the answer provides no semantic guarantees whatsoever
about the value that you get from `init()`, and in your use case you do not
care and simply want to invoke the initializer and return what you get from
it. Now, in a perfect world where the reflection facilities that Swift
provided were essentially free of performance cost, would you object to
that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious
that Obj-C bridging is non-negotiable for Swift, and of course a bridged
type is all sorts of different under the hood from a native type. I'm going
to take a wild guess that no other use case would pass that high bar for
magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> >> wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz >> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < >> swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < >> swift-evolution@swift.org> wrote:

> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying
that if it makes sense for an object to have a default constructor, it
makes sense for it to conform to the protocol which I agree with 100%.

On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org> wrote:

on Sun Dec 25 2016, Daniel Leping <swift-evolution@swift.org> wrote:

> You are right, usually it's required to implement a protocol which is
not a

> good approach. The best is plain objects which can be used
independently of

> ORM if needed (as DTOs, i.e.).

>

> I was thinking of DefaultConstructable as a protocol automatically
applied

> to any class/struct having a default init, which is really logical for

> me.

Swift doesn't do implicit conformance. It always has to be declared

explicitly. I'm pretty sure Doug Gregor can explain why better than I

My two cents:
1) T() should NOT have anything to do with zero or even “default". (If we need semantic zero, create a protocol with a .zero static func/var)
2) This comes up enough in my programming, and is such a fundamental concept, that T() probably DOES deserve special treatment in the form of a protocol
3) The semantics of that protocol would be “Things which can be created without any additional information beyond their Type”
4) We should keep working on the name

As to whether the protocol needs to be implicit… I am unsure. It may be enough to have the standard library + cocoa types conform where appropriate. On the other hand, I can’t think of any type having T() which would not fit the above semantics… and I would guess around 85~90% of types have it, so it may be worth the trouble to make it implicit in this specific case. I am on the fence, but would probably lean against making it implicit.

Thanks,
Jon

···

On Dec 25, 2016, at 11:28 PM, Daniel Leping via swift-evolution <swift-evolution@swift.org> wrote:

It's not a matter of probability, but rather of certainty. Please.

On Mon, 26 Dec 2016 at 12:56 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
I totally agree Swift is an opinionated language and it's good.

Also I have been thinking of DefaultConstructable vs reflection for generic factories and I would prefer to stick to the protocol as it gives compile time type safety check. With reflection the only way is to through an exception if there is no init. So again +1 pro to DefaultConstructable.

Well, you can't argue both ways. Either so many types implement `init()` that it is unusually onerous to type, in which case you will gain nearly nothing from compile-time checks, or not so many types implement `init()`, and you can conform those types to a protocol by yourself :slight_smile:

On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY conformed by all classes.

What you say is just another approach to the same issue and we can argue for eternity. However, I am very positive with syntactic sugar and this one falls exactly to sugar category. Make people lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc (proven by time, btw) on board sounds very appealing to me. I wish to see Swift a very diverse ecosystem and this Pitch serves exactly this goal.

Yes, we should let others chime in on this issue. I will just end by saying that I've always appreciated how the core team has been very careful and thoughtful about certain precepts, and how they've stuck to the idea that Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought put into semantic meaning. The notion that protocols should carry semantics has been adhered to very strictly. This is why I think this proposal does do harm, because it explicitly rejects that very important idea, one that can only be upheld by people and not compilers.

(Another semantic distinction observed in Swift is that a boolean value has semantic meaning and is not just a bit; this is why, for instance, the FloatingPoint protocols define an `enum FloatingPointSign { case plus, minus }`--because floating point sign has different _semantics_ from a Bool.)

Let's just see if it gets any more positive votes.

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory pattern" and just wanted to point out that at least some of those patterns seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type implement `init()`?" is properly a reflection question and not a protocol conformance question: the answer provides no semantic guarantees whatsoever about the value that you get from `init()`, and in your use case you do not care and simply want to invoke the initializer and return what you get from it. Now, in a perfect world where the reflection facilities that Swift provided were essentially free of performance cost, would you object to that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious that Obj-C bridging is non-negotiable for Swift, and of course a bridged type is all sorts of different under the hood from a native type. I'm going to take a wild guess that no other use case would pass that high bar for magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
I'm giving a wider range, which is about ANY factory pattern related stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of the stated reasons for failable initializers was: "Failable initializers eliminate the most common reason for factory methods in Swift... Using the failable initializer allows greater use of Swift’s uniform construction syntax, which simplifies the language by eliminating the confusion and duplication between initializers and factory methods." <https://developer.apple.com/swift/blog/?id=17 <https://developer.apple.com/swift/blog/?id=17>>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
Well, reflection is a huge performance drop. Protocol conformance is way better.

I'm not sure how huge it would be in the grand scheme of things; in your example, you are still evaluating a train of protocol conformances and casting at runtime. Of course, compiler magic can be fast, but I still don't see how this is a "very common use case" (as you write) that would justify magic equivalent to that for Objective-C bridging, which is what you're saying it should be. If `DefaultConstructible` is useful only when it's magic and the specific use case is dependency injection/inversion of control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
I'm not arguing for implicit conformance in general, but I'm telling that DefaultConstructable is the same basic level as AnyObject, which is conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with "automatic compiler magic" conformance to DefaultConstructable for any object having a default constructor as it really is a very basic stuff. Otherwise you will have to add explicit conformance to it in almost every class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes semantic meaning for `init()` that, as he described, means that it cannot apply to every type that implements `init()`. However, he also just said that he thinks that all types with `init()` should conform, so I guess I'm confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds like reflection to me, not protocol conformance. For the record, I look forward to the day when AnyObject magic is removed; I assume it is coming eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> Swift doesn't do implicit conformance. It always has to be declared
explicitly. I'm pretty sure Doug Gregor can explain why better than I
could.

I don't think Daniel was arguing for implicit conformance, he's saying that if it makes sense for an object to have a default constructor, it makes sense for it to conform to the protocol which I agree with 100%.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

That is really the key question, and until it can be answered
satisfactorily, I will continue to be -1 on the idea. My sense of the
arguments for the protocol is that they amount to, “please, it's
obvious; to do anything else would be absurd.” That sort of response
tends to make me even more suspicious of any idea. There are lots of
things we've done in Swift that looked absurd to someone but turned out
to be exactly right.

Here is a bit of truly friendly advice for those proposing
DefaultConstructible. If you really believe in this idea and you want
the proposal to be a succeess, you should try to approach the problem
this way:

1. Understand the principle behind what Wu and I are saying.
2. Set aside what appears to be your base assumption that the protocol
   makes sense and pretend you need to be convinced.
3. Sincerely answer the question Wu is asking in such a way that it
   would convince the “unconvinced you.”

HTH,

···

on Mon Dec 26 2016, Xiaodi Wu <xiaodi.wu-AT-gmail.com> wrote:

The question still remains unanswered, what generic algorithms are enabled
by having such a protocol?

--
-Dave

The question still remains unanswered, what generic algorithms are enabled
by having such a protocol? After a long chain, the answer so far is `return
T()`. Indeed, afaict, the semantics you are proposing would explicitly
limit us to that.

···

On Mon, Dec 26, 2016 at 09:32 Jonathan Hull <jhull@gbis.com> wrote:

My two cents:
1) T() should NOT have anything to do with zero or even “default". (If we
need semantic zero, create a protocol with a .zero static func/var)
2) This comes up enough in my programming, and is such a fundamental
concept, that T() probably DOES deserve special treatment in the form of a
protocol
3) The semantics of that protocol would be “Things which can be created
without any additional information beyond their Type”
4) We should keep working on the name

As to whether the protocol needs to be implicit… I am unsure. It may be
enough to have the standard library + cocoa types conform where
appropriate. On the other hand, I can’t think of any type having T() which
would not fit the above semantics… and I would guess around 85~90% of types
have it, so it may be worth the trouble to make it implicit in this
specific case. I am on the fence, but would probably lean against making
it implicit.

Thanks,
Jon

On Dec 25, 2016, at 11:28 PM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

It's not a matter of probability, but rather of certainty. Please.

On Mon, 26 Dec 2016 at 12:56 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I totally agree Swift is an opinionated language and it's good.

Also I have been thinking of DefaultConstructable vs reflection for
generic factories and I would prefer to stick to the protocol as it gives
compile time type safety check. With reflection the only way is to through
an exception if there is no init. So again +1 pro to DefaultConstructable.

Well, you can't argue both ways. Either so many types implement `init()`
that it is unusually onerous to type, in which case you will gain nearly
nothing from compile-time checks, or not so many types implement `init()`,
and you can conform those types to a protocol by yourself :slight_smile:

On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY
conformed by all classes.

What you say is just another approach to the same issue and we can argue
for eternity. However, I am very positive with syntactic sugar and this one
falls exactly to sugar category. Make people lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc (proven
by time, btw) on board sounds very appealing to me. I wish to see Swift a
very diverse ecosystem and this Pitch serves exactly this goal.

Yes, we should let others chime in on this issue. I will just end by
saying that I've always appreciated how the core team has been very careful
and thoughtful about certain precepts, and how they've stuck to the idea
that Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought put into
semantic meaning. The notion that protocols should carry semantics has been
adhered to very strictly. This is why I think this proposal does do harm,
because it explicitly rejects that very important idea, one that can only
be upheld by people and not compilers.

(Another semantic distinction observed in Swift is that a boolean value
has semantic meaning and is not just a bit; this is why, for instance, the
FloatingPoint protocols define an `enum FloatingPointSign { case plus,
minus }`--because floating point sign has different _semantics_ from a
Bool.)

Let's just see if it gets any more positive votes.

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory
pattern" and just wanted to point out that at least some of those patterns
seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type
implement `init()`?" is properly a reflection question and not a protocol
conformance question: the answer provides no semantic guarantees whatsoever
about the value that you get from `init()`, and in your use case you do not
care and simply want to invoke the initializer and return what you get from
it. Now, in a perfect world where the reflection facilities that Swift
provided were essentially free of performance cost, would you object to
that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious
that Obj-C bridging is non-negotiable for Swift, and of course a bridged
type is all sorts of different under the hood from a native type. I'm going
to take a wild guess that no other use case would pass that high bar for
magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm giving a wider range, which is about ANY factory pattern related
stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of
the stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

Well, reflection is a huge performance drop. Protocol conformance is way
better.

I'm not sure how huge it would be in the grand scheme of things; in your
example, you are still evaluating a train of protocol conformances and
casting at runtime. Of course, compiler magic can be fast, but I still
don't see how this is a "very common use case" (as you write) that would
justify magic equivalent to that for Objective-C bridging, which is what
you're saying it should be. If `DefaultConstructible` is useful only when
it's magic and the specific use case is dependency injection/inversion of
control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz> > wrote:

I'm not arguing for implicit conformance in general, but I'm telling that
DefaultConstructable is the same basic level as AnyObject, which is
conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with
"automatic compiler magic" conformance to DefaultConstructable for any
object having a default constructor as it really is a very basic stuff.
Otherwise you will have to add explicit conformance to it in almost every
class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes
semantic meaning for `init()` that, as he described, means that it cannot
apply to every type that implements `init()`. However, he also just said
that he thinks that all types with `init()` should conform, so I guess I'm
confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds
like reflection to me, not protocol conformance. For the record, I look
forward to the day when AnyObject magic is removed; I assume it is coming
eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution < > swift-evolution@swift.org> wrote:

Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

Just because something is simple, doesn’t mean it isn’t important. You can do a lot with ‘return T()’ that you can’t do without it (namely make a T).

Equatable is similar. Semantically, it just lets you ask if two instances of the same type are equal. The fact that it only does one thing doesn’t mean it isn’t useful or necessary as a small part of a lot of different algorithms.

I find I use T() most often in factory or builder patterns, but any creational pattern may need it. It is also often used together with other protocols. The code is all pretty boring…

  func hasOptionalParam( a: T = T() ) {} //The caller can pass in a specific thing, or just leave out the parameter to use a vanilla one

or

  var t = T()
  t.somethingFancy() //Provided by unrelated protocol
  t.moreFancy()
  return t

or

  var t = T()
  if t is SomeOtherProtocol {
    //Do something fancy
  }
  if t is YetAnotherProtocol {
    //Do something else fancy
  }
  return t

All of the “fancy stuff” will be done by conforming to other protocols, but those protocols may have nothing to do with creation (nor should they). There is nothing wrong with requiring conformance to multiple protocols...

Thanks,
Jon

···

On Dec 26, 2016, at 7:10 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

The question still remains unanswered, what generic algorithms are enabled by having such a protocol? After a long chain, the answer so far is `return T()`. Indeed, afaict, the semantics you are proposing would explicitly limit us to that.

On Mon, Dec 26, 2016 at 09:32 Jonathan Hull <jhull@gbis.com <mailto:jhull@gbis.com>> wrote:
My two cents:
1) T() should NOT have anything to do with zero or even “default". (If we need semantic zero, create a protocol with a .zero static func/var)
2) This comes up enough in my programming, and is such a fundamental concept, that T() probably DOES deserve special treatment in the form of a protocol
3) The semantics of that protocol would be “Things which can be created without any additional information beyond their Type”
4) We should keep working on the name

As to whether the protocol needs to be implicit… I am unsure. It may be enough to have the standard library + cocoa types conform where appropriate. On the other hand, I can’t think of any type having T() which would not fit the above semantics… and I would guess around 85~90% of types have it, so it may be worth the trouble to make it implicit in this specific case. I am on the fence, but would probably lean against making it implicit.

Thanks,
Jon

On Dec 25, 2016, at 11:28 PM, Daniel Leping via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

It's not a matter of probability, but rather of certainty. Please.

On Mon, 26 Dec 2016 at 12:56 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
I totally agree Swift is an opinionated language and it's good.

Also I have been thinking of DefaultConstructable vs reflection for generic factories and I would prefer to stick to the protocol as it gives compile time type safety check. With reflection the only way is to through an exception if there is no init. So again +1 pro to DefaultConstructable.

Well, you can't argue both ways. Either so many types implement `init()` that it is unusually onerous to type, in which case you will gain nearly nothing from compile-time checks, or not so many types implement `init()`, and you can conform those types to a protocol by yourself :slight_smile:

On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY conformed by all classes.

What you say is just another approach to the same issue and we can argue for eternity. However, I am very positive with syntactic sugar and this one falls exactly to sugar category. Make people lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc (proven by time, btw) on board sounds very appealing to me. I wish to see Swift a very diverse ecosystem and this Pitch serves exactly this goal.

Yes, we should let others chime in on this issue. I will just end by saying that I've always appreciated how the core team has been very careful and thoughtful about certain precepts, and how they've stuck to the idea that Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought put into semantic meaning. The notion that protocols should carry semantics has been adhered to very strictly. This is why I think this proposal does do harm, because it explicitly rejects that very important idea, one that can only be upheld by people and not compilers.

(Another semantic distinction observed in Swift is that a boolean value has semantic meaning and is not just a bit; this is why, for instance, the FloatingPoint protocols define an `enum FloatingPointSign { case plus, minus }`--because floating point sign has different _semantics_ from a Bool.)

Let's just see if it gets any more positive votes.

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any factory pattern" and just wanted to point out that at least some of those patterns seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this type implement `init()`?" is properly a reflection question and not a protocol conformance question: the answer provides no semantic guarantees whatsoever about the value that you get from `init()`, and in your use case you do not care and simply want to invoke the initializer and return what you get from it. Now, in a perfect world where the reflection facilities that Swift provided were essentially free of performance cost, would you object to that characterization?

You're certainly right that `AnyObject` has magic. It's rather obvious that Obj-C bridging is non-negotiable for Swift, and of course a bridged type is all sorts of different under the hood from a native type. I'm going to take a wild guess that no other use case would pass that high bar for magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
I'm giving a wider range, which is about ANY factory pattern related stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift? One of the stated reasons for failable initializers was: "Failable initializers eliminate the most common reason for factory methods in Swift... Using the failable initializer allows greater use of Swift’s uniform construction syntax, which simplifies the language by eliminating the confusion and duplication between initializers and factory methods." <https://developer.apple.com/swift/blog/?id=17 <https://developer.apple.com/swift/blog/?id=17>>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
Well, reflection is a huge performance drop. Protocol conformance is way better.

I'm not sure how huge it would be in the grand scheme of things; in your example, you are still evaluating a train of protocol conformances and casting at runtime. Of course, compiler magic can be fast, but I still don't see how this is a "very common use case" (as you write) that would justify magic equivalent to that for Objective-C bridging, which is what you're saying it should be. If `DefaultConstructible` is useful only when it's magic and the specific use case is dependency injection/inversion of control, then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>> wrote:
I'm not arguing for implicit conformance in general, but I'm telling that DefaultConstructable is the same basic level as AnyObject, which is conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive with "automatic compiler magic" conformance to DefaultConstructable for any object having a default constructor as it really is a very basic stuff. Otherwise you will have to add explicit conformance to it in almost every class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he proposes semantic meaning for `init()` that, as he described, means that it cannot apply to every type that implements `init()`. However, he also just said that he thinks that all types with `init()` should conform, so I guess I'm confused which way that is.

At base, you want a way of knowing if a type has `init()`. That sounds like reflection to me, not protocol conformance. For the record, I look forward to the day when AnyObject magic is removed; I assume it is coming eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Just because something is simple, doesn’t mean it isn’t important. You can do a lot with ‘return
T()’ that you can’t do without it (namely make a T).

Sure, but the question remains: *should* you make a T in those
circumstances? Maybe you

With DefaultConstructible, you don't know anything about the value of
this T. There is nothing you can do with it, reliably. If the default
constructability requirement is part of some larger protocol like
RangeReplaceableCollection, then you can say things like, “this makes an
empty collection,” and “a default-constructed instance is equivalent to an
instance on which you've called removeAll.” That doesn't argue for
factoring the init() out into its own protocol. It argues for including
the init() requirement in every protocol where it forms an important
part of the protocol's semantic basis operations.

Equatable is similar. Semantically, it just lets you ask if two instances of the same type are
equal.

Equatable is *very* different. It has a whole page of semantics. Read
from “Equality implies substitutability” to the end of the page at
http://swiftdoc.org/v3.0/protocol/Equatable/.

The fact that it only does one thing doesn’t mean it isn’t useful or
necessary as a small part of a lot of different algorithms.

I find I use T() most often in factory or builder patterns, but any creational pattern may need it.
It is also often used together with other protocols. The code is all pretty boring…

  func hasOptionalParam( a: T = T() ) {} //The caller can pass in
a specific thing, or just leave out the parameter to use a vanilla one
or

  var t = T()
  t.somethingFancy() //Provided by unrelated protocol
  t.moreFancy()
  return t

or

  var t = T()
  if t is SomeOtherProtocol {
    //Do something fancy
  }
  if t is YetAnotherProtocol {
    //Do something else fancy
  }
  return t

All of the “fancy stuff” will be done by conforming to other protocols, but those protocols may have
nothing to do with creation (nor should they). There is nothing wrong with requiring conformance to
multiple protocols...

No, there isn't. There *is* something wrong with slicing meaningful
protocols up into bits that have only syntactic value, though. I
suspect that's what's going on here.

···

on Mon Dec 26 2016, Jonathan Hull <swift-evolution@swift.org> wrote:

Thanks,
Jon

On Dec 26, 2016, at 7:10 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

The question still remains unanswered, what generic algorithms are
enabled by having such a protocol? After a long chain, the answer so
far is `return T()`. Indeed, afaict, the semantics you are proposing
would explicitly limit us to that.

On Mon, Dec 26, 2016 at 09:32 Jonathan Hull >> <jhull@gbis.com <mailto:jhull@gbis.com>> wrote:
My two cents:
1) T() should NOT have anything to do with zero or even
“default". (If we need semantic zero, create a protocol with a .zero
static func/var)
2) This comes up enough in my programming, and is such a fundamental
concept, that T() probably DOES deserve special treatment in the
form of a protocol
3) The semantics of that protocol would be “Things which can be
created without any additional information beyond their Type”
4) We should keep working on the name

As to whether the protocol needs to be implicit… I am unsure. It
may be enough to have the standard library + cocoa types conform
where appropriate. On the other hand, I can’t think of any type
having T() which would not fit the above semantics… and I would
guess around 85~90% of types have it, so it may be worth the trouble
to make it implicit in this specific case. I am on the fence, but
would probably lean against making it implicit.

Thanks,
Jon

On Dec 25, 2016, at 11:28 PM, Daniel Leping via swift-evolution >>> <swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>> >>> wrote:

It's not a matter of probability, but rather of certainty. Please.

On Mon, 26 Dec 2016 at 12:56 Xiaodi Wu >>> <xiaodi.wu@gmail.com >>> <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping >>> <daniel@crossroadlabs.xyz >>> <mailto:daniel@crossroadlabs.xyz>> >>> wrote:
I totally agree Swift is an opinionated language and it's good.

Also I have been thinking of DefaultConstructable vs reflection for
generic factories and I would prefer to stick to the protocol as it
gives compile time type safety check. With reflection the only way
is to through an exception if there is no init. So again +1 pro to
DefaultConstructable.

Well, you can't argue both ways. Either so many types implement
`init()` that it is unusually onerous to type, in which case you
will gain nearly nothing from compile-time checks, or not so many
types implement `init()`, and you can conform those types to a
protocol by yourself :slight_smile:

On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu >>> <xiaodi.wu@gmail.com >>> <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping >>> <daniel@crossroadlabs.xyz >>> <mailto:daniel@crossroadlabs.xyz>> >>> wrote:
Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY conformed by all classes.

What you say is just another approach to the same issue and we can
argue for eternity. However, I am very positive with syntactic
sugar and this one falls exactly to sugar category. Make people
lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc
(proven by time, btw) on board sounds very appealing to me. I wish
to see Swift a very diverse ecosystem and this Pitch serves exactly
this goal.

Yes, we should let others chime in on this issue. I will just end
by saying that I've always appreciated how the core team has been
very careful and thoughtful about certain precepts, and how they've
stuck to the idea that Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought
put into semantic meaning. The notion that protocols should carry
semantics has been adhered to very strictly. This is why I think
this proposal does do harm, because it explicitly rejects that very
important idea, one that can only be upheld by people and not
compilers.

(Another semantic distinction observed in Swift is that a boolean
value has semantic meaning and is not just a bit; this is why, for
instance, the FloatingPoint protocols define an `enum
FloatingPointSign { case plus, minus }`--because floating point
sign has different _semantics_ from a Bool.)

Let's just see if it gets any more positive votes.

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu >>> <xiaodi.wu@gmail.com >>> <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping >>> <daniel@crossroadlabs.xyz >>> <mailto:daniel@crossroadlabs.xyz>> >>> wrote:
I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any
factory pattern" and just wanted to point out that at least some of
those patterns seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this
type implement `init()`?" is properly a reflection question and not
a protocol conformance question: the answer provides no semantic
guarantees whatsoever about the value that you get from `init()`,
and in your use case you do not care and simply want to invoke the
initializer and return what you get from it. Now, in a perfect
world where the reflection facilities that Swift provided were
essentially free of performance cost, would you object to that
characterization?

You're certainly right that `AnyObject` has magic. It's rather
obvious that Obj-C bridging is non-negotiable for Swift, and of
course a bridged type is all sorts of different under the hood from
a native type. I'm going to take a wild guess that no other use
case would pass that high bar for magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu >>> <xiaodi.wu@gmail.com >>> <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping >>> <daniel@crossroadlabs.xyz >>> <mailto:daniel@crossroadlabs.xyz>> >>> wrote:
I'm giving a wider range, which is about ANY factory pattern
related stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift?
One of the stated reasons for failable initializers was: "Failable
initializers eliminate the most common reason for factory methods
in Swift... Using the failable initializer allows greater use of
Swift’s uniform construction syntax, which simplifies the language
by eliminating the confusion and duplication between initializers
and factory methods."
<https://developer.apple.com/swift/blog/?id=17
<https://developer.apple.com/swift/blog/?id=17>>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu >>> <xiaodi.wu@gmail.com >>> <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping >>> <daniel@crossroadlabs.xyz >>> <mailto:daniel@crossroadlabs.xyz>> >>> wrote:
Well, reflection is a huge performance drop. Protocol conformance is way better.

I'm not sure how huge it would be in the grand scheme of things; in
your example, you are still evaluating a train of protocol
conformances and casting at runtime. Of course, compiler magic can
be fast, but I still don't see how this is a "very common use case"
(as you write) that would justify magic equivalent to that for
Objective-C bridging, which is what you're saying it should be. If
`DefaultConstructible` is useful only when it's magic and the
specific use case is dependency injection/inversion of control,
then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu >>> <xiaodi.wu@gmail.com >>> <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping >>> <daniel@crossroadlabs.xyz >>> <mailto:daniel@crossroadlabs.xyz>> >>> wrote:
I'm not arguing for implicit conformance in general, but I'm
telling that DefaultConstructable is the same basic level as
AnyObject, which is conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive
with "automatic compiler magic" conformance to DefaultConstructable
for any object having a default constructor as it really is a very
basic stuff. Otherwise you will have to add explicit conformance to
it in almost every class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he
proposes semantic meaning for `init()` that, as he described, means
that it cannot apply to every type that implements
`init()`. However, he also just said that he thinks that all types
with `init()` should conform, so I guess I'm confused which way
that is.

At base, you want a way of knowing if a type has `init()`. That
sounds like reflection to me, not protocol conformance. For the
record, I look forward to the day when AnyObject magic is removed;
I assume it is coming eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu >>> <xiaodi.wu@gmail.com >>> <mailto:xiaodi.wu@gmail.com>> wrote:
On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution >>> <swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>> >>> wrote:
Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution >>> <swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>> >>> wrote:

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

Just because something is simple, doesn’t mean it isn’t important. You can do a lot with ‘return
T()’ that you can’t do without it (namely make a T).

Sure, but the question remains: *should* you make a T in those
circumstances? Maybe you

With DefaultConstructible, you don't know anything about the value of
this T. There is nothing you can do with it, reliably. If the default
constructability requirement is part of some larger protocol like
RangeReplaceableCollection, then you can say things like, “this makes an
empty collection,” and “a default-constructed instance is equivalent to an
instance on which you've called removeAll.” That doesn't argue for
factoring the init() out into its own protocol. It argues for including
the init() requirement in every protocol where it forms an important
part of the protocol's semantic basis operations.

Ok, I think I see what you are saying now.

Equatable is similar. Semantically, it just lets you ask if two instances of the same type are
equal.

Equatable is *very* different. It has a whole page of semantics. Read
from “Equality implies substitutability” to the end of the page at
http://swiftdoc.org/v3.0/protocol/Equatable/.

The fact that it only does one thing doesn’t mean it isn’t useful or
necessary as a small part of a lot of different algorithms.

I find I use T() most often in factory or builder patterns, but any creational pattern may need it.
It is also often used together with other protocols. The code is all pretty boring…

  func hasOptionalParam( a: T = T() ) {} //The caller can pass in
a specific thing, or just leave out the parameter to use a vanilla one
or

  var t = T()
  t.somethingFancy() //Provided by unrelated protocol
  t.moreFancy()
  return t

or

  var t = T()
  if t is SomeOtherProtocol {
    //Do something fancy
  }
  if t is YetAnotherProtocol {
    //Do something else fancy
  }
  return t

All of the “fancy stuff” will be done by conforming to other protocols, but those protocols may have
nothing to do with creation (nor should they). There is nothing wrong with requiring conformance to
multiple protocols...

No, there isn't. There *is* something wrong with slicing meaningful
protocols up into bits that have only syntactic value, though. I
suspect that's what's going on here.

It’s quite possible. I kept having it in a bunch of larger protocols, where it felt a bit tacked on and out of place, so I started factoring it out by itself which felt cleaner.

When you keep writing the same code over and over, the impulse is to factor it out so you only write it once (and so that functions you write need the fewest guarantees possible), but perhaps that was the wrong instinct here...

···

On Dec 26, 2016, at 9:29 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:
on Mon Dec 26 2016, Jonathan Hull <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Thanks,
Jon

On Dec 26, 2016, at 7:10 AM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

The question still remains unanswered, what generic algorithms are
enabled by having such a protocol? After a long chain, the answer so
far is `return T()`. Indeed, afaict, the semantics you are proposing
would explicitly limit us to that.

On Mon, Dec 26, 2016 at 09:32 Jonathan Hull >>> <jhull@gbis.com <mailto:jhull@gbis.com> <mailto:jhull@gbis.com <mailto:jhull@gbis.com>>> wrote:
My two cents:
1) T() should NOT have anything to do with zero or even
“default". (If we need semantic zero, create a protocol with a .zero
static func/var)
2) This comes up enough in my programming, and is such a fundamental
concept, that T() probably DOES deserve special treatment in the
form of a protocol
3) The semantics of that protocol would be “Things which can be
created without any additional information beyond their Type”
4) We should keep working on the name

As to whether the protocol needs to be implicit… I am unsure. It
may be enough to have the standard library + cocoa types conform
where appropriate. On the other hand, I can’t think of any type
having T() which would not fit the above semantics… and I would
guess around 85~90% of types have it, so it may be worth the trouble
to make it implicit in this specific case. I am on the fence, but
would probably lean against making it implicit.

Thanks,
Jon

On Dec 25, 2016, at 11:28 PM, Daniel Leping via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> >>>> wrote:

It's not a matter of probability, but rather of certainty. Please.

On Mon, 26 Dec 2016 at 12:56 Xiaodi Wu >>>> <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com> >>>> <mailto:xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>>> wrote:
On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping >>>> <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz> >>>> <mailto:daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>>> >>>> wrote:
I totally agree Swift is an opinionated language and it's good.

Also I have been thinking of DefaultConstructable vs reflection for
generic factories and I would prefer to stick to the protocol as it
gives compile time type safety check. With reflection the only way
is to through an exception if there is no init. So again +1 pro to
DefaultConstructable.

Well, you can't argue both ways. Either so many types implement
`init()` that it is unusually onerous to type, in which case you
will gain nearly nothing from compile-time checks, or not so many
types implement `init()`, and you can conform those types to a
protocol by yourself :slight_smile:

On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu >>>> <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com> >>>> <mailto:xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>>> wrote:
On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping >>>> <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz> >>>> <mailto:daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>>> >>>> wrote:
Well, AnyObject exists on Linux with no bridging. Still it's IMPLICITELY conformed by all classes.

What you say is just another approach to the same issue and we can
argue for eternity. However, I am very positive with syntactic
sugar and this one falls exactly to sugar category. Make people
lifes easier :wink:

Moreover it will never ever do any harm.

Adding an easy way to get another set of frameworks/approaches/etc
(proven by time, btw) on board sounds very appealing to me. I wish
to see Swift a very diverse ecosystem and this Pitch serves exactly
this goal.

Yes, we should let others chime in on this issue. I will just end
by saying that I've always appreciated how the core team has been
very careful and thoughtful about certain precepts, and how they've
stuck to the idea that Swift is an _opinionated_ language.

In particular, I appreciate that there's a huge amount of thought
put into semantic meaning. The notion that protocols should carry
semantics has been adhered to very strictly. This is why I think
this proposal does do harm, because it explicitly rejects that very
important idea, one that can only be upheld by people and not
compilers.

(Another semantic distinction observed in Swift is that a boolean
value has semantic meaning and is not just a bit; this is why, for
instance, the FloatingPoint protocols define an `enum
FloatingPointSign { case plus, minus }`--because floating point
sign has different _semantics_ from a Bool.)

Let's just see if it gets any more positive votes.

On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu >>>> <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com> >>>> <mailto:xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>>> wrote:
On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping >>>> <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz> >>>> <mailto:daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>>> >>>> wrote:
I believe you're confusing in-class factory methods with factory pattern.

Factories can be separate objects and it's a very different situation.

Fair, but I understand both to fall under the umbrella of "any
factory pattern" and just wanted to point out that at least some of
those patterns seem to be discouraged :slight_smile:

In any case, I think it's fair to say that the question "does this
type implement `init()`?" is properly a reflection question and not
a protocol conformance question: the answer provides no semantic
guarantees whatsoever about the value that you get from `init()`,
and in your use case you do not care and simply want to invoke the
initializer and return what you get from it. Now, in a perfect
world where the reflection facilities that Swift provided were
essentially free of performance cost, would you object to that
characterization?

You're certainly right that `AnyObject` has magic. It's rather
obvious that Obj-C bridging is non-negotiable for Swift, and of
course a bridged type is all sorts of different under the hood from
a native type. I'm going to take a wild guess that no other use
case would pass that high bar for magic.

On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu >>>> <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com> >>>> <mailto:xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>>> wrote:
On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping >>>> <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz> >>>> <mailto:daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>>> >>>> wrote:
I'm giving a wider range, which is about ANY factory pattern
related stuff. Doesn't look to be narrow to me.

I thought factory methods were regarded as undesirable in Swift?
One of the stated reasons for failable initializers was: "Failable
initializers eliminate the most common reason for factory methods
in Swift... Using the failable initializer allows greater use of
Swift’s uniform construction syntax, which simplifies the language
by eliminating the confusion and duplication between initializers
and factory methods."
<https://developer.apple.com/swift/blog/?id=17 <https://developer.apple.com/swift/blog/?id=17>
<https://developer.apple.com/swift/blog/?id=17 <https://developer.apple.com/swift/blog/?id=17>>>

On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu >>>> <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com> >>>> <mailto:xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>>> wrote:
On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping >>>> <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz> >>>> <mailto:daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>>> >>>> wrote:
Well, reflection is a huge performance drop. Protocol conformance is way better.

I'm not sure how huge it would be in the grand scheme of things; in
your example, you are still evaluating a train of protocol
conformances and casting at runtime. Of course, compiler magic can
be fast, but I still don't see how this is a "very common use case"
(as you write) that would justify magic equivalent to that for
Objective-C bridging, which is what you're saying it should be. If
`DefaultConstructible` is useful only when it's magic and the
specific use case is dependency injection/inversion of control,
then we're getting very specialized here.

On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu >>>> <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com> >>>> <mailto:xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>>> wrote:
On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping >>>> <daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz> >>>> <mailto:daniel@crossroadlabs.xyz <mailto:daniel@crossroadlabs.xyz>>> >>>> wrote:
I'm not arguing for implicit conformance in general, but I'm
telling that DefaultConstructable is the same basic level as
AnyObject, which is conformed implicitly.

Shortly, I'm against implicit conformance in general. I'm positive
with "automatic compiler magic" conformance to DefaultConstructable
for any object having a default constructor as it really is a very
basic stuff. Otherwise you will have to add explicit conformance to
it in almost every class of yours (annoying).

Well, this sounds very different from Adam's proposal, where he
proposes semantic meaning for `init()` that, as he described, means
that it cannot apply to every type that implements
`init()`. However, he also just said that he thinks that all types
with `init()` should conform, so I guess I'm confused which way
that is.

At base, you want a way of knowing if a type has `init()`. That
sounds like reflection to me, not protocol conformance. For the
record, I look forward to the day when AnyObject magic is removed;
I assume it is coming eventually.

On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu >>>> <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com> >>>> <mailto:xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>>> wrote:
On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> >>>> wrote:
Thank you, Adam!

Wait, are you arguing for implicit conformance or not?

On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> >>>> wrote:

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Equatable is *very* different. It has a whole page of semantics.

DefaultConstructible comes in handy when you want to write an algorithm
that works with a constant sized buffer and you need to initialize the
buffer to some default values that will be replaced once you have actual
data. Or some objects can initialize themselves from static data (e.g. each
object has a sequential id and uses a counter that it increments in init).
But in all cases, you want to make sure that the array is statically sized.

For me, it also has some implicit meaning of a zero which I agree might be
a stretch in general but this is more explicit in cases where types are
comparable. Order theory requires a bottom or zero for a reason.
Fundamentally, if two elements are comparable, it makes sense to ask what
is the distance between them. And the magnitude of these elements is
generally measured as a distance from some sort of origin or zero.

Protocols (a.k.a. concepts) are not just bags of syntax; unless you can

attach semantics to the operations, you can't write useful generic algorithms
against them. So we shouldn't have DefaultConstructible for
the same reason we shouldn't have “Plusable” to represent something that
lets you write x + x.

Haha, I totally have an Addable protocol. Out of curiosity why is it bad?
My use case is for example a struct that's fundamentally a wrapper around
some numerical value (int) and not all numerical operations make sense but
e.g. addition makes total sense. E.g. a midi note event where addition
gives you a transposition but multiplication doesn't make sense. In this
case the default value (zero) is the value that results in no
transposition. And if I extend this, what if I have two equally sized
arrays of midi events where one represents a transposition and the other
represents the notes I'm transposing and I want to combine them to produce
the transposed notes, I can write this algorithm as

extension Collection where Iterator.Element: Addable {

        func transpose(_ other: Self) -> [Iterator.Element] {

            assert(count == other.count)

            return zip(self, other).map { $0 + $1 }

    }

}
I'm not sure if this example is too concrete and specific to my needs but
I've been trying to use Swift as a language for making these little
algebras with a pretty good degree of success but some things like this
would be pretty helpful I think.

···

On Mon, Dec 26, 2016 at 9:29 AM, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

on Mon Dec 26 2016, Jonathan Hull <swift-evolution@swift.org> wrote:

> Just because something is simple, doesn’t mean it isn’t important. You
can do a lot with ‘return
> T()’ that you can’t do without it (namely make a T).

Sure, but the question remains: *should* you make a T in those
circumstances? Maybe you

With DefaultConstructible, you don't know anything about the value of
this T. There is nothing you can do with it, reliably. If the default
constructability requirement is part of some larger protocol like
RangeReplaceableCollection, then you can say things like, “this makes an
empty collection,” and “a default-constructed instance is equivalent to an
instance on which you've called removeAll.” That doesn't argue for
factoring the init() out into its own protocol. It argues for including
the init() requirement in every protocol where it forms an important
part of the protocol's semantic basis operations.

> Equatable is similar. Semantically, it just lets you ask if two
instances of the same type are
> equal.

Equatable is *very* different. It has a whole page of semantics. Read
from “Equality implies substitutability” to the end of the page at
http://swiftdoc.org/v3.0/protocol/Equatable/.

> The fact that it only does one thing doesn’t mean it isn’t useful or
> necessary as a small part of a lot of different algorithms.
>
> I find I use T() most often in factory or builder patterns, but any
creational pattern may need it.
> It is also often used together with other protocols. The code is all
pretty boring…
>
> func hasOptionalParam( a: T = T() ) {} //The caller can pass in
> a specific thing, or just leave out the parameter to use a vanilla one
> or
>
> var t = T()
> t.somethingFancy() //Provided by unrelated protocol
> t.moreFancy()
> return t
>
> or
>
> var t = T()
> if t is SomeOtherProtocol {
> //Do something fancy
> }
> if t is YetAnotherProtocol {
> //Do something else fancy
> }
> return t
>
> All of the “fancy stuff” will be done by conforming to other protocols,
but those protocols may have
> nothing to do with creation (nor should they). There is nothing wrong
with requiring conformance to
> multiple protocols...

No, there isn't. There *is* something wrong with slicing meaningful
protocols up into bits that have only syntactic value, though. I
suspect that's what's going on here.

>
>
> Thanks,
> Jon
>
>> On Dec 26, 2016, at 7:10 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
>>
>> The question still remains unanswered, what generic algorithms are
>> enabled by having such a protocol? After a long chain, the answer so
>> far is `return T()`. Indeed, afaict, the semantics you are proposing
>> would explicitly limit us to that.
>>
>>
>> On Mon, Dec 26, 2016 at 09:32 Jonathan Hull > >> <jhull@gbis.com <mailto:jhull@gbis.com>> wrote:
>> My two cents:
>> 1) T() should NOT have anything to do with zero or even
>> “default". (If we need semantic zero, create a protocol with a .zero
>> static func/var)
>> 2) This comes up enough in my programming, and is such a fundamental
>> concept, that T() probably DOES deserve special treatment in the
>> form of a protocol
>> 3) The semantics of that protocol would be “Things which can be
>> created without any additional information beyond their Type”
>> 4) We should keep working on the name
>>
>> As to whether the protocol needs to be implicit… I am unsure. It
>> may be enough to have the standard library + cocoa types conform
>> where appropriate. On the other hand, I can’t think of any type
>> having T() which would not fit the above semantics… and I would
>> guess around 85~90% of types have it, so it may be worth the trouble
>> to make it implicit in this specific case. I am on the fence, but
>> would probably lean against making it implicit.
>>
>> Thanks,
>> Jon
>>
>>
>>> On Dec 25, 2016, at 11:28 PM, Daniel Leping via swift-evolution > >>> <swift-evolution@swift.org > >>> <mailto:swift-evolution@swift.org>> > >>> wrote:
>>>
>>> It's not a matter of probability, but rather of certainty. Please.
>>>
>>> On Mon, 26 Dec 2016 at 12:56 Xiaodi Wu > >>> <xiaodi.wu@gmail.com > >>> <mailto:xiaodi.wu@gmail.com>> wrote:
>>> On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping > >>> <daniel@crossroadlabs.xyz > >>> <mailto:daniel@crossroadlabs.xyz>> > >>> wrote:
>>> I totally agree Swift is an opinionated language and it's good.
>>>
>>> Also I have been thinking of DefaultConstructable vs reflection for
>>> generic factories and I would prefer to stick to the protocol as it
>>> gives compile time type safety check. With reflection the only way
>>> is to through an exception if there is no init. So again +1 pro to
>>> DefaultConstructable.
>>>
>>> Well, you can't argue both ways. Either so many types implement
>>> `init()` that it is unusually onerous to type, in which case you
>>> will gain nearly nothing from compile-time checks, or not so many
>>> types implement `init()`, and you can conform those types to a
>>> protocol by yourself :slight_smile:
>>>
>>>
>>> On Mon, 26 Dec 2016 at 12:32 Xiaodi Wu > >>> <xiaodi.wu@gmail.com > >>> <mailto:xiaodi.wu@gmail.com>> wrote:
>>> On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping > >>> <daniel@crossroadlabs.xyz > >>> <mailto:daniel@crossroadlabs.xyz>> > >>> wrote:
>>> Well, AnyObject exists on Linux with no bridging. Still it's
IMPLICITELY conformed by all classes.
>>>
>>> What you say is just another approach to the same issue and we can
>>> argue for eternity. However, I am very positive with syntactic
>>> sugar and this one falls exactly to sugar category. Make people
>>> lifes easier :wink:
>>>
>>> Moreover it will never ever do any harm.
>>>
>>> Adding an easy way to get another set of frameworks/approaches/etc
>>> (proven by time, btw) on board sounds very appealing to me. I wish
>>> to see Swift a very diverse ecosystem and this Pitch serves exactly
>>> this goal.
>>>
>>> Yes, we should let others chime in on this issue. I will just end
>>> by saying that I've always appreciated how the core team has been
>>> very careful and thoughtful about certain precepts, and how they've
>>> stuck to the idea that Swift is an _opinionated_ language.
>>>
>>> In particular, I appreciate that there's a huge amount of thought
>>> put into semantic meaning. The notion that protocols should carry
>>> semantics has been adhered to very strictly. This is why I think
>>> this proposal does do harm, because it explicitly rejects that very
>>> important idea, one that can only be upheld by people and not
>>> compilers.
>>>
>>> (Another semantic distinction observed in Swift is that a boolean
>>> value has semantic meaning and is not just a bit; this is why, for
>>> instance, the FloatingPoint protocols define an `enum
>>> FloatingPointSign { case plus, minus }`--because floating point
>>> sign has different _semantics_ from a Bool.)
>>>
>>> Let's just see if it gets any more positive votes.
>>>
>>> On Mon, 26 Dec 2016 at 12:10 Xiaodi Wu > >>> <xiaodi.wu@gmail.com > >>> <mailto:xiaodi.wu@gmail.com>> wrote:
>>> On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping > >>> <daniel@crossroadlabs.xyz > >>> <mailto:daniel@crossroadlabs.xyz>> > >>> wrote:
>>> I believe you're confusing in-class factory methods with factory
pattern.
>>>
>>> Factories can be separate objects and it's a very different situation.
>>>
>>> Fair, but I understand both to fall under the umbrella of "any
>>> factory pattern" and just wanted to point out that at least some of
>>> those patterns seem to be discouraged :slight_smile:
>>>
>>> In any case, I think it's fair to say that the question "does this
>>> type implement `init()`?" is properly a reflection question and not
>>> a protocol conformance question: the answer provides no semantic
>>> guarantees whatsoever about the value that you get from `init()`,
>>> and in your use case you do not care and simply want to invoke the
>>> initializer and return what you get from it. Now, in a perfect
>>> world where the reflection facilities that Swift provided were
>>> essentially free of performance cost, would you object to that
>>> characterization?
>>>
>>> You're certainly right that `AnyObject` has magic. It's rather
>>> obvious that Obj-C bridging is non-negotiable for Swift, and of
>>> course a bridged type is all sorts of different under the hood from
>>> a native type. I'm going to take a wild guess that no other use
>>> case would pass that high bar for magic.
>>>
>>>
>>> On Mon, 26 Dec 2016 at 11:46 Xiaodi Wu > >>> <xiaodi.wu@gmail.com > >>> <mailto:xiaodi.wu@gmail.com>> wrote:
>>> On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping > >>> <daniel@crossroadlabs.xyz > >>> <mailto:daniel@crossroadlabs.xyz>> > >>> wrote:
>>> I'm giving a wider range, which is about ANY factory pattern
>>> related stuff. Doesn't look to be narrow to me.
>>>
>>> I thought factory methods were regarded as undesirable in Swift?
>>> One of the stated reasons for failable initializers was: "Failable
>>> initializers eliminate the most common reason for factory methods
>>> in Swift... Using the failable initializer allows greater use of
>>> Swift’s uniform construction syntax, which simplifies the language
>>> by eliminating the confusion and duplication between initializers
>>> and factory methods."
>>> <https://developer.apple.com/swift/blog/?id=17
>>> <https://developer.apple.com/swift/blog/?id=17>>
>>>
>>>
>>> On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu > >>> <xiaodi.wu@gmail.com > >>> <mailto:xiaodi.wu@gmail.com>> wrote:
>>> On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping > >>> <daniel@crossroadlabs.xyz > >>> <mailto:daniel@crossroadlabs.xyz>> > >>> wrote:
>>> Well, reflection is a huge performance drop. Protocol conformance is
way better.
>>>
>>> I'm not sure how huge it would be in the grand scheme of things; in
>>> your example, you are still evaluating a train of protocol
>>> conformances and casting at runtime. Of course, compiler magic can
>>> be fast, but I still don't see how this is a "very common use case"
>>> (as you write) that would justify magic equivalent to that for
>>> Objective-C bridging, which is what you're saying it should be. If
>>> `DefaultConstructible` is useful only when it's magic and the
>>> specific use case is dependency injection/inversion of control,
>>> then we're getting very specialized here.
>>>
>>>
>>> On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu > >>> <xiaodi.wu@gmail.com > >>> <mailto:xiaodi.wu@gmail.com>> wrote:
>>> On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping > >>> <daniel@crossroadlabs.xyz > >>> <mailto:daniel@crossroadlabs.xyz>> > >>> wrote:
>>> I'm not arguing for implicit conformance in general, but I'm
>>> telling that DefaultConstructable is the same basic level as
>>> AnyObject, which is conformed implicitly.
>>>
>>> Shortly, I'm against implicit conformance in general. I'm positive
>>> with "automatic compiler magic" conformance to DefaultConstructable
>>> for any object having a default constructor as it really is a very
>>> basic stuff. Otherwise you will have to add explicit conformance to
>>> it in almost every class of yours (annoying).
>>>
>>> Well, this sounds very different from Adam's proposal, where he
>>> proposes semantic meaning for `init()` that, as he described, means
>>> that it cannot apply to every type that implements
>>> `init()`. However, he also just said that he thinks that all types
>>> with `init()` should conform, so I guess I'm confused which way
>>> that is.
>>>
>>> At base, you want a way of knowing if a type has `init()`. That
>>> sounds like reflection to me, not protocol conformance. For the
>>> record, I look forward to the day when AnyObject magic is removed;
>>> I assume it is coming eventually.
>>>
>>>
>>> On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu > >>> <xiaodi.wu@gmail.com > >>> <mailto:xiaodi.wu@gmail.com>> wrote:
>>> On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution > >>> <swift-evolution@swift.org > >>> <mailto:swift-evolution@swift.org>> > >>> wrote:
>>> Thank you, Adam!
>>>
>>> Wait, are you arguing for implicit conformance or not?
>>>
>>> On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution > >>> <swift-evolution@swift.org > >>> <mailto:swift-evolution@swift.org>> > >>> wrote:
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>

--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Terms of Service

Privacy Policy

Cookie Policy