[Pitch] Add the DefaultConstructible protocol to the standard library

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

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...

Factoring out implementations is one thing, and definitely a good place
for DRY. Factoring out requirements should only be done when the
commonality enables some kind of generic programming. In fact, the
opposite—clustering requirements together to create concepts
(a.k.a. protocols)—is an important part of the generic programming
process. See
https://stlab.adobe.com/wiki/index.php/Runtime_Concepts#Concept

···

on Mon Dec 26 2016, Jonathan Hull <swift-evolution@swift.org> wrote:

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
<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
<https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

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.

In that case the default construction is just a waste of cycles; you
should construct the values when you have them.

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).

I can't visualize such an algorithm

But in all cases, you want to make sure that the array is statically
sized.

Then construct the array when you have the values.

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.

I'm not arguing about the usefulness or importance of zero! I'm saying
“default constructibility” isn't a thing you can use for anything (other
than two-phase initialization, which is a bad idea anyway) absent any
associated semantics. It's like saying, “give me a protocol that lets
me call a foo() method on an instance.”

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?

Because you can't write a meaningful generic algorithm over it if all it
does is confer the validity of the syntax "a + a".

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.

Addition of two midi notes doesn't make sense. Addition of integers to
midi notes does.

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

A MIDI note is not a transposition, if for no other reason than that
MIDI notes are unsigned and transpositions are signed. They're more
akin to pointers, which have an associated distance type. Your MIDI
notes should conform to Strideable.

···

on Mon Dec 26 2016, Adam Nemecek <swift-evolution@swift.org> wrote:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

> 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.

`ManagedBuffer` is the standard library base class that offers facilities
for managing buffers. If there's a concrete use case that isn't served,
then the argument would be to improve `ManagedBuffer` or to design other
types or protocols for that use case, not to add a protocol to conform
every type that implements `init()`.

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.

Careful, total ordering does not require a notion of an origin; not at all.
The distance between two values of type T does not itself need to be of
type T, and there need be no value of type T that represents any sort of
"zero." Moreover, one can have distances being strideable opaque types that
can't even be initialized (i.e. distances can be of a type U such that two
values can have a relative distance between them, but `U.init()` isn't
public).

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.

This example does not make sense, computationally or musically. Firstly,
transposition is the shifting of pitch by an _interval_; if `Self` is a
MIDI note (as you imply below), transposition cannot be by addition of type
`Self` but rather of `Self.Stride`. Secondly, you can absolutely multiply a
note by an integer factor. Doubling the frequency shifts the pitch of a
note by an octave; tripling the frequency gets you an octave + a perfect
fifth. If you work through the mathematics behind this, you'll understand
the issues behind equal temperament and well temperament.

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.

You are describing a `Strideable` type. That is already in the stdlib. If
you want to use `+` to denote `advanced(by:)`, that's easy to add by
extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

···

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

`ManagedBuffer` is the standard library base class that offers facilities

for managing buffers. If there's a concrete use case that isn't served,
then the argument would be to improve `ManagedBuffer` or to design other
types or protocols for that use case, not to add a protocol to conform
every type that implements `init()`.

I'd prefer not to deal with raw storage unless necessary.

The distance between two values of type T does not itself need to be of

type T,

Never said otherwise.

Moreover, one can have distances being strideable opaque types that can't

even be initialized

You sure can. Doesn't disprove any of my points.

This example does not make sense, computationally or musically.

You mean that it does not make any sense to you. I have two midi streams
(and they are midi) and I want to use one midi note to transpose the other.
I'm pretty sure that I can find a machine that does this in hardware if I
really try. Does the fact that such machine might exist imbue the concept
of midi addition with any meaning?

You are describing a `Strideable` type. That is already in the stdlib. If

you want to use `+` to denote `advanced(by:)`, that's easy to add by
extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

I don't always need the closure property.

Doubling the frequency shifts the pitch of a note by an octave; tripling

the frequency gets you an octave + a perfect fifth. If you work through the
mathematics behind this, you'll understand the issues behind equal
temperament and well temperament.

You are not multiplying pitch by pitch but pitch by number. Pitch + Pitch
makes complete sense if you accept the midi worldview which doesn't say
anything about intervals and you realize that the computational distinction
between the two is tenuous at best. But this discussion is neither here,
nor there.

···

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

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

> 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.

`ManagedBuffer` is the standard library base class that offers facilities
for managing buffers. If there's a concrete use case that isn't served,
then the argument would be to improve `ManagedBuffer` or to design other
types or protocols for that use case, not to add a protocol to conform
every type that implements `init()`.

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.

Careful, total ordering does not require a notion of an origin; not at
all. The distance between two values of type T does not itself need to be
of type T, and there need be no value of type T that represents any sort of
"zero." Moreover, one can have distances being strideable opaque types that
can't even be initialized (i.e. distances can be of a type U such that two
values can have a relative distance between them, but `U.init()` isn't
public).

> 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.

This example does not make sense, computationally or musically. Firstly,
transposition is the shifting of pitch by an _interval_; if `Self` is a
MIDI note (as you imply below), transposition cannot be by addition of type
`Self` but rather of `Self.Stride`. Secondly, you can absolutely multiply a
note by an integer factor. Doubling the frequency shifts the pitch of a
note by an octave; tripling the frequency gets you an octave + a perfect
fifth. If you work through the mathematics behind this, you'll understand
the issues behind equal temperament and well temperament.

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.

You are describing a `Strideable` type. That is already in the stdlib. If
you want to use `+` to denote `advanced(by:)`, that's easy to add by
extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

There's a Channel Coarse Tuning SysEx message for this purpose. Even if
there weren't one, that hypothetical machine is, logically speaking,
stripping the absolute-pitch-ness off of the MIDI note used for
transposition and using it as a relative pitch offset. It's like the
relationship between dates on the calendar and time intervals (10 days).

···

on Mon Dec 26 2016, Adam Nemecek <adamnemecek-AT-gmail.com> wrote:

`ManagedBuffer` is the standard library base class that offers facilities

for managing buffers. If there's a concrete use case that isn't served,
then the argument would be to improve `ManagedBuffer` or to design other
types or protocols for that use case, not to add a protocol to conform
every type that implements `init()`.

I'd prefer not to deal with raw storage unless necessary.

The distance between two values of type T does not itself need to be of

type T,

Never said otherwise.

Moreover, one can have distances being strideable opaque types that can't

even be initialized

You sure can. Doesn't disprove any of my points.

This example does not make sense, computationally or musically.

You mean that it does not make any sense to you. I have two midi streams
(and they are midi) and I want to use one midi note to transpose the other.
I'm pretty sure that I can find a machine that does this in hardware if I
really try. Does the fact that such machine might exist imbue the concept
of midi addition with any meaning?

--
-Dave

here weren't one, that hypothetical machine is, logically speaking,

stripping the absolute-pitch-ness off of the MIDI note used for
transposition and using it as a relative pitch offset.

Indeed.

It's like the relationship between dates on the calendar and time

intervals (10 days).

No it's not. Two days cannot occur at the same time. Two events totally
can. It's more like signals that combine.

···

On Mon, Dec 26, 2016 at 2:31 PM, Dave Abrahams <dabrahams@apple.com> wrote:

on Mon Dec 26 2016, Adam Nemecek <adamnemecek-AT-gmail.com> wrote:

>> `ManagedBuffer` is the standard library base class that offers
facilities
> for managing buffers. If there's a concrete use case that isn't served,
> then the argument would be to improve `ManagedBuffer` or to design other
> types or protocols for that use case, not to add a protocol to conform
> every type that implements `init()`.
>
> I'd prefer not to deal with raw storage unless necessary.
>
>> The distance between two values of type T does not itself need to be of
> type T,
>
> Never said otherwise.
>
>> Moreover, one can have distances being strideable opaque types that
can't
> even be initialized
>
> You sure can. Doesn't disprove any of my points.
>
>> This example does not make sense, computationally or musically.
>
> You mean that it does not make any sense to you. I have two midi streams
> (and they are midi) and I want to use one midi note to transpose the
other.
> I'm pretty sure that I can find a machine that does this in hardware if I
> really try. Does the fact that such machine might exist imbue the concept
> of midi addition with any meaning?

There's a Channel Coarse Tuning SysEx message for this purpose. Even if
there weren't one, that hypothetical machine is, logically speaking,
stripping the absolute-pitch-ness off of the MIDI note used for
transposition and using it as a relative pitch offset. It's like the
relationship between dates on the calendar and time intervals (10 days).

--
-Dave

here weren't one, that hypothetical machine is, logically speaking,

stripping the absolute-pitch-ness off of the MIDI note used for
transposition and using it as a relative pitch offset.

Indeed.

It's like the relationship between dates on the calendar and time

intervals (10 days).

No it's not. Two days cannot occur at the same time. Two events totally
can. It's more like signals that combine.

Heh, you're missing my point because there's a “time” component to both
systems but that wasn't intended to be a connection. It's like the
relationship between addresses in memory (pointers) and offsets.

If you want to treat your midi notes as bare numbers that can be added
and have no semantics of absolute pitch until you send them to a synth,
be my guest. I would tend not to design a system that way, but if it
works for you, more power to ya.

I think I've offered all the help here that I have to give, and I don't
feel I'm successfully getting my point across, so with respect, I'm
going to retire from this discussion now. I'm supposed to be on
vacation :slight_smile:

···

on Mon Dec 26 2016, Adam Nemecek <adamnemecek-AT-gmail.com> wrote:

On Mon, Dec 26, 2016 at 2:31 PM, Dave Abrahams <dabrahams@apple.com> wrote:

on Mon Dec 26 2016, Adam Nemecek <adamnemecek-AT-gmail.com> wrote:

>> `ManagedBuffer` is the standard library base class that offers
facilities
> for managing buffers. If there's a concrete use case that isn't served,
> then the argument would be to improve `ManagedBuffer` or to design other
> types or protocols for that use case, not to add a protocol to conform
> every type that implements `init()`.
>
> I'd prefer not to deal with raw storage unless necessary.
>
>> The distance between two values of type T does not itself need to be of
> type T,
>
> Never said otherwise.
>
>> Moreover, one can have distances being strideable opaque types that
can't
> even be initialized
>
> You sure can. Doesn't disprove any of my points.
>
>> This example does not make sense, computationally or musically.
>
> You mean that it does not make any sense to you. I have two midi streams
> (and they are midi) and I want to use one midi note to transpose the
other.
> I'm pretty sure that I can find a machine that does this in hardware if I
> really try. Does the fact that such machine might exist imbue the concept
> of midi addition with any meaning?

There's a Channel Coarse Tuning SysEx message for this purpose. Even if
there weren't one, that hypothetical machine is, logically speaking,
stripping the absolute-pitch-ness off of the MIDI note used for
transposition and using it as a relative pitch offset. It's like the
relationship between dates on the calendar and time intervals (10 days).

--
-Dave

--
-Dave

The midi conversation went south the second it started.

Heh, you're missing my point

No you are missing mine. It doesn't make sense for two days to combine. It
totally makes sense for two signals to combine.

If you want to treat your midi notes as bare numbers that can be added

and have no semantics of absolute pitch until you send them to a synth,
be my guest.

These things are fundamentally numbers, you can call them whatever you want.

I think I've offered all the help here that I have to give, and I don't

feel I'm successfully getting my point across, so with respect, I'm
going to retire from this discussion now. I'm supposed to be on
vacation :slight_smile:

That's two of us.

···

On Mon, Dec 26, 2016 at 2:49 PM, Dave Abrahams <dabrahams@apple.com> wrote:

on Mon Dec 26 2016, Adam Nemecek <adamnemecek-AT-gmail.com> wrote:

>> here weren't one, that hypothetical machine is, logically speaking,
> stripping the absolute-pitch-ness off of the MIDI note used for
> transposition and using it as a relative pitch offset.
>
> Indeed.
>
>> It's like the relationship between dates on the calendar and time
> intervals (10 days).
>
> No it's not. Two days cannot occur at the same time. Two events totally
> can. It's more like signals that combine.

Heh, you're missing my point because there's a “time” component to both
systems but that wasn't intended to be a connection. It's like the
relationship between addresses in memory (pointers) and offsets.

If you want to treat your midi notes as bare numbers that can be added
and have no semantics of absolute pitch until you send them to a synth,
be my guest. I would tend not to design a system that way, but if it
works for you, more power to ya.

I think I've offered all the help here that I have to give, and I don't
feel I'm successfully getting my point across, so with respect, I'm
going to retire from this discussion now. I'm supposed to be on
vacation :slight_smile:

> On Mon, Dec 26, 2016 at 2:31 PM, Dave Abrahams <dabrahams@apple.com> > wrote:
>
>>
>> on Mon Dec 26 2016, Adam Nemecek <adamnemecek-AT-gmail.com> wrote:
>>
>> >> `ManagedBuffer` is the standard library base class that offers
>> facilities
>> > for managing buffers. If there's a concrete use case that isn't
served,
>> > then the argument would be to improve `ManagedBuffer` or to design
other
>> > types or protocols for that use case, not to add a protocol to conform
>> > every type that implements `init()`.
>> >
>> > I'd prefer not to deal with raw storage unless necessary.
>> >
>> >> The distance between two values of type T does not itself need to be
of
>> > type T,
>> >
>> > Never said otherwise.
>> >
>> >> Moreover, one can have distances being strideable opaque types that
>> can't
>> > even be initialized
>> >
>> > You sure can. Doesn't disprove any of my points.
>> >
>> >> This example does not make sense, computationally or musically.
>> >
>> > You mean that it does not make any sense to you. I have two midi
streams
>> > (and they are midi) and I want to use one midi note to transpose the
>> other.
>> > I'm pretty sure that I can find a machine that does this in hardware
if I
>> > really try. Does the fact that such machine might exist imbue the
concept
>> > of midi addition with any meaning?
>>
>> There's a Channel Coarse Tuning SysEx message for this purpose. Even if
>> there weren't one, that hypothetical machine is, logically speaking,
>> stripping the absolute-pitch-ness off of the MIDI note used for
>> transposition and using it as a relative pitch offset. It's like the
>> relationship between dates on the calendar and time intervals (10 days).
>>
>> --
>> -Dave
>>

--
-Dave

> `ManagedBuffer` is the standard library base class that offers
facilities for managing buffers. If there's a concrete use case that isn't
served, then the argument would be to improve `ManagedBuffer` or to design
other types or protocols for that use case, not to add a protocol to
conform every type that implements `init()`.

I'd prefer not to deal with raw storage unless necessary.

Huh? You just said that one usage scenario was the allocation of buffers of
known size. If you're unsatisfied with the API for that, you're welcome to
propose better ones. The point is that this is not a convincing use case,
as you claim, for `DefaultConstructible`, but rather for better buffer APIs.

> The distance between two values of type T does not itself need to be of
type T,

Never said otherwise.

> Moreover, one can have distances being strideable opaque types that
can't even be initialized

You sure can. Doesn't disprove any of my points.

Sure it does. You asserted that where a type is comparable, it "generally"
makes sense to measure distance from "some sort of origin or zero." And I'm
showing you why it does not generally make sense at all. There is no nexus
between comparability and "some sort of origin or zero" from which to
measure absolute distance, as you state.

This example does not make sense, computationally or musically.

You mean that it does not make any sense to you.

No, I mean that you are incorrect.

I have two midi streams (and they are midi) and I want to use one midi
note to transpose the other.

There is no such concept in music theory as "using one note to transpose
the other." Sorry.

I'm pretty sure that I can find a machine that does this in hardware if I
really try. Does the fact that such machine might exist imbue the concept
of midi addition with any meaning?

> You are describing a `Strideable` type. That is already in the stdlib.
If you want to use `+` to denote `advanced(by:)`, that's easy to add by
extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

I don't always need the closure property.

What closure property? My question was, why are you not using `Strideable`?
You are describing its semantics. I'm not sure what closure you are
referring to.

Doubling the frequency shifts the pitch of a note by an octave; tripling
the frequency gets you an octave + a perfect fifth. If you work through the
mathematics behind this, you'll understand the issues behind equal
temperament and well temperament.

You are not multiplying pitch by pitch but pitch by number. Pitch + Pitch
makes complete sense if you accept the midi worldview which doesn't say
anything about intervals

Ooh boy. There is no worldview in music that "doesn't say anything about
intervals," I can assure you of that.

···

On Mon, Dec 26, 2016 at 4:28 PM, Adam Nemecek <adamnemecek@gmail.com> wrote:

and you realize that the computational distinction between the two is
tenuous at best. But this discussion is neither here, nor there.

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

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

> 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.

`ManagedBuffer` is the standard library base class that offers facilities
for managing buffers. If there's a concrete use case that isn't served,
then the argument would be to improve `ManagedBuffer` or to design other
types or protocols for that use case, not to add a protocol to conform
every type that implements `init()`.

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.

Careful, total ordering does not require a notion of an origin; not at
all. The distance between two values of type T does not itself need to be
of type T, and there need be no value of type T that represents any sort of
"zero." Moreover, one can have distances being strideable opaque types that
can't even be initialized (i.e. distances can be of a type U such that two
values can have a relative distance between them, but `U.init()` isn't
public).

> 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.

This example does not make sense, computationally or musically. Firstly,
transposition is the shifting of pitch by an _interval_; if `Self` is a
MIDI note (as you imply below), transposition cannot be by addition of type
`Self` but rather of `Self.Stride`. Secondly, you can absolutely multiply a
note by an integer factor. Doubling the frequency shifts the pitch of a
note by an octave; tripling the frequency gets you an octave + a perfect
fifth. If you work through the mathematics behind this, you'll understand
the issues behind equal temperament and well temperament.

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.

You are describing a `Strideable` type. That is already in the stdlib. If
you want to use `+` to denote `advanced(by:)`, that's easy to add by
extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Huh? You just said that one usage scenario was the allocation of buffers

of known size. If you're unsatisfied with the API for that, you're welcome
to propose better ones. The point is that this is not a convincing use
case, as you claim, for `DefaultConstructible`, but rather for better
buffer APIs.

I've brought up several situation where I'd use these. I don't want a
better buffer API, I want a way of expressing myself in a way that seems
natural to me.

There is no nexus between comparability and "some sort of origin or zero"

from which to measure absolute distance, as you state.

There is. Elements are equal if the distance between them is zero. Why does
Comparability also require Equatability?

Ooh boy. There is no worldview in music that "doesn't say anything about

intervals," I can assure you of that.

https://github.com/midiguchi/midiguchi

Do you see the zip operation? Could you tell me what it does? Note that I
have no relationship to this project. I can find more if I really try. So
now there is a precedence, so what's next? Are you going to tell me that
this doesn't count? Why not? I was aware of this library even before this
discussion btw.

No, I mean that you are incorrect.

Well if you say so it must be true. Lol.

What closure property? My question was, why are you not using

`Strideable`? You are describing its semantics. I'm not sure what closure
you are referring to.

Algebraic closure.

As I explained earlier, your argument _is_ circular. But it's clear now

you will not accept that being point out to you by multiple people
independently.

It's not circular, it's I use data point to point out that this is a common
pattern.

···

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

On Mon, Dec 26, 2016 at 4:28 PM, Adam Nemecek <adamnemecek@gmail.com> > wrote:

> `ManagedBuffer` is the standard library base class that offers
facilities for managing buffers. If there's a concrete use case that isn't
served, then the argument would be to improve `ManagedBuffer` or to design
other types or protocols for that use case, not to add a protocol to
conform every type that implements `init()`.

I'd prefer not to deal with raw storage unless necessary.

Huh? You just said that one usage scenario was the allocation of buffers
of known size. If you're unsatisfied with the API for that, you're welcome
to propose better ones. The point is that this is not a convincing use
case, as you claim, for `DefaultConstructible`, but rather for better
buffer APIs.

> The distance between two values of type T does not itself need to be
of type T,

Never said otherwise.

> Moreover, one can have distances being strideable opaque types that
can't even be initialized

You sure can. Doesn't disprove any of my points.

Sure it does. You asserted that where a type is comparable, it "generally"
makes sense to measure distance from "some sort of origin or zero." And I'm
showing you why it does not generally make sense at all. There is no nexus
between comparability and "some sort of origin or zero" from which to
measure absolute distance, as you state.

> This example does not make sense, computationally or musically.

You mean that it does not make any sense to you.

No, I mean that you are incorrect.

I have two midi streams (and they are midi) and I want to use one midi
note to transpose the other.

There is no such concept in music theory as "using one note to transpose
the other." Sorry.

I'm pretty sure that I can find a machine that does this in hardware if I
really try. Does the fact that such machine might exist imbue the concept
of midi addition with any meaning?

> You are describing a `Strideable` type. That is already in the stdlib.
If you want to use `+` to denote `advanced(by:)`, that's easy to add by
extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

I don't always need the closure property.

What closure property? My question was, why are you not using
`Strideable`? You are describing its semantics. I'm not sure what closure
you are referring to.

> Doubling the frequency shifts the pitch of a note by an octave;

tripling the frequency gets you an octave + a perfect fifth. If you work
through the mathematics behind this, you'll understand the issues behind
equal temperament and well temperament.

You are not multiplying pitch by pitch but pitch by number. Pitch + Pitch
makes complete sense if you accept the midi worldview which doesn't say
anything about intervals

Ooh boy. There is no worldview in music that "doesn't say anything about
intervals," I can assure you of that.

and you realize that the computational distinction between the two is
tenuous at best. But this discussion is neither here, nor there.

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

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

> 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.

`ManagedBuffer` is the standard library base class that offers
facilities for managing buffers. If there's a concrete use case that isn't
served, then the argument would be to improve `ManagedBuffer` or to design
other types or protocols for that use case, not to add a protocol to
conform every type that implements `init()`.

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.

Careful, total ordering does not require a notion of an origin; not at
all. The distance between two values of type T does not itself need to be
of type T, and there need be no value of type T that represents any sort of
"zero." Moreover, one can have distances being strideable opaque types that
can't even be initialized (i.e. distances can be of a type U such that two
values can have a relative distance between them, but `U.init()` isn't
public).

> 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.

This example does not make sense, computationally or musically. Firstly,
transposition is the shifting of pitch by an _interval_; if `Self` is a
MIDI note (as you imply below), transposition cannot be by addition of type
`Self` but rather of `Self.Stride`. Secondly, you can absolutely multiply a
note by an integer factor. Doubling the frequency shifts the pitch of a
note by an octave; tripling the frequency gets you an octave + a perfect
fifth. If you work through the mathematics behind this, you'll understand
the issues behind equal temperament and well temperament.

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.

You are describing a `Strideable` type. That is already in the stdlib.
If you want to use `+` to denote `advanced(by:)`, that's easy to add by
extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

That is a long story about utility and the relationship of strict-weak
orderings to total orderings that I'd love to explain someday... but
really, it has nothing to do with zero.

···

on Mon Dec 26 2016, Adam Nemecek <adamnemecek-AT-gmail.com> wrote:

Why does Comparability also require Equatability?

--
-Dave

> Huh? You just said that one usage scenario was the allocation of
buffers of known size. If you're unsatisfied with the API for that, you're
welcome to propose better ones. The point is that this is not a convincing
use case, as you claim, for `DefaultConstructible`, but rather for better
buffer APIs.

I've brought up several situation where I'd use these. I don't want a
better buffer API, I want a way of expressing myself in a way that seems
natural to me.

If you were to outline in greater detail how allocation of buffers of known
size was not ergonomic today, then that would be motivation for a better
API for allocation of buffers. It does not help your case for
`DefaultConstructible`.

> There is no nexus between comparability and "some sort of origin or
zero" from which to measure absolute distance, as you state.

There is. Elements are equal if the distance between them is zero. Why
does Comparability also require Equatability?

Again, that is not a distance from some sort of origin. The relative
distance between two values of type T might be "zero," but that "zero" may
not be of type T. In that case, there would be no origin from which to
measure the distance of values of type T.

> Ooh boy. There is no worldview in music that "doesn't say anything
about intervals," I can assure you of that.

https://github.com/midiguchi/midiguchi

Do you see the zip operation? Could you tell me what it does?

I do not see the zip operation. I searched the GitHub readme for the word
"zip" and do not see anything. However, I do see the transpose function:

input = 口.input.open('nanoKEY2 KEYBOARD')
transposed = 口.transpose(3)(input)

And boy, that `3` sure looks like an interval.

Note that I have no relationship to this project. I can find more if I
really try. So now there is a precedence, so what's next? Are you going to
tell me that this doesn't count? Why not? I was aware of this library even
before this discussion btw.

> No, I mean that you are incorrect.

Well if you say so it must be true. Lol.

Well, there _is_ a piece of paper with shiny bits and my name on it,
sitting in my closet somewhere, that says I know what I'm talking about
when it comes to music theory :slight_smile:

What closure property? My question was, why are you not using
`Strideable`? You are describing its semantics. I'm not sure what closure
you are referring to.

Algebraic closure.

This is not answering my question--why aren't you using `Strideable`? What
closure are you talking about? I don't see one.

···

On Mon, Dec 26, 2016 at 4:59 PM, Adam Nemecek <adamnemecek@gmail.com> wrote:

> As I explained earlier, your argument _is_ circular. But it's clear now
you will not accept that being point out to you by multiple people
independently.

It's not circular, it's I use data point to point out that this is a
common pattern.

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

On Mon, Dec 26, 2016 at 4:28 PM, Adam Nemecek <adamnemecek@gmail.com> >> wrote:

> `ManagedBuffer` is the standard library base class that offers
facilities for managing buffers. If there's a concrete use case that isn't
served, then the argument would be to improve `ManagedBuffer` or to design
other types or protocols for that use case, not to add a protocol to
conform every type that implements `init()`.

I'd prefer not to deal with raw storage unless necessary.

Huh? You just said that one usage scenario was the allocation of buffers
of known size. If you're unsatisfied with the API for that, you're welcome
to propose better ones. The point is that this is not a convincing use
case, as you claim, for `DefaultConstructible`, but rather for better
buffer APIs.

> The distance between two values of type T does not itself need to be
of type T,

Never said otherwise.

> Moreover, one can have distances being strideable opaque types that
can't even be initialized

You sure can. Doesn't disprove any of my points.

Sure it does. You asserted that where a type is comparable, it
"generally" makes sense to measure distance from "some sort of origin or
zero." And I'm showing you why it does not generally make sense at all.
There is no nexus between comparability and "some sort of origin or zero"
from which to measure absolute distance, as you state.

> This example does not make sense, computationally or musically.

You mean that it does not make any sense to you.

No, I mean that you are incorrect.

I have two midi streams (and they are midi) and I want to use one midi
note to transpose the other.

There is no such concept in music theory as "using one note to transpose
the other." Sorry.

I'm pretty sure that I can find a machine that does this in hardware if
I really try. Does the fact that such machine might exist imbue the concept
of midi addition with any meaning?

> You are describing a `Strideable` type. That is already in the
stdlib. If you want to use `+` to denote `advanced(by:)`, that's easy to
add by extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

I don't always need the closure property.

What closure property? My question was, why are you not using
`Strideable`? You are describing its semantics. I'm not sure what closure
you are referring to.

> Doubling the frequency shifts the pitch of a note by an octave;

tripling the frequency gets you an octave + a perfect fifth. If you work
through the mathematics behind this, you'll understand the issues behind
equal temperament and well temperament.

You are not multiplying pitch by pitch but pitch by number. Pitch +
Pitch makes complete sense if you accept the midi worldview which doesn't
say anything about intervals

Ooh boy. There is no worldview in music that "doesn't say anything about
intervals," I can assure you of that.

and you realize that the computational distinction between the two is
tenuous at best. But this discussion is neither here, nor there.

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

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

> 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.

`ManagedBuffer` is the standard library base class that offers
facilities for managing buffers. If there's a concrete use case that isn't
served, then the argument would be to improve `ManagedBuffer` or to design
other types or protocols for that use case, not to add a protocol to
conform every type that implements `init()`.

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.

Careful, total ordering does not require a notion of an origin; not at
all. The distance between two values of type T does not itself need to be
of type T, and there need be no value of type T that represents any sort of
"zero." Moreover, one can have distances being strideable opaque types that
can't even be initialized (i.e. distances can be of a type U such that two
values can have a relative distance between them, but `U.init()` isn't
public).

> 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.

This example does not make sense, computationally or musically.
Firstly, transposition is the shifting of pitch by an _interval_; if `Self`
is a MIDI note (as you imply below), transposition cannot be by addition of
type `Self` but rather of `Self.Stride`. Secondly, you can absolutely
multiply a note by an integer factor. Doubling the frequency shifts the
pitch of a note by an octave; tripling the frequency gets you an octave + a
perfect fifth. If you work through the mathematics behind this, you'll
understand the issues behind equal temperament and well temperament.

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.

You are describing a `Strideable` type. That is already in the stdlib.
If you want to use `+` to denote `advanced(by:)`, that's easy to add by
extension. I'm not sure why you decided to reinvent it and call it
`Addable`.

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Terms of Service

Privacy Policy

Cookie Policy