[Pitch] Add the DefaultConstructible protocol to the standard library

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

···

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

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

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

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."
<Failable Initializers - Swift Blog - Apple Developer <Failable Initializers - Swift Blog - Apple Developer;
<Failable Initializers - Swift Blog - Apple Developer <Failable Initializers - Swift Blog - Apple Developer;

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&gt;

--
-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&gt;

_______________________________________________
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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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

1 Like

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

1 Like

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

···

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

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

> 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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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.

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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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.

GitHub - midiguchi/midiguchi: midiguchi - MIDI I/O using Functional Reactive Programming with Bacon.js. Transpose, remap, filter, manipulate arbitrarily, or synthesize MIDI events with ease.

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

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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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?

Many data types don't have a notion of distance, but still define a total
ordering, which I think was the original point. What would be the distance
between two strings? If "ab" < "abc", what is the distance between them?
Even though the empty string is the multiplicative identity for strings,
it's not an "origin" from which other strings can be said to have a
distance from.

···

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

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

GitHub - midiguchi/midiguchi: midiguchi - MIDI I/O using Functional Reactive Programming with Bacon.js. Transpose, remap, filter, manipulate arbitrarily, or synthesize MIDI events with ease.

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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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

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

> Even though the empty string is the multiplicative identity for strings,
it's not an "origin" from which other strings can be said to have a
distance from.

Imagination is the limit. You can create a sequence of string permutations
and assign integers to each permutation. Distance between "ab" and "abc" is
the same as the distance between their permutation numbers. Whether this
distance makes sense for strings is another question.

But that's entirely arbitrary—strings already have well-defined equality
and total ordering without defining distance. The fact that one can craft a
definition of distance that is consistent with the system doesn't mean that
distance is a *requirement* for equality/comparability to be defined—a
total ordering is simply a binary relation on the set with the appropriate
properties.

···

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

On Mon, Dec 26, 2016 at 2:13 PM, Tony Allevato <tony.allevato@gmail.com> > wrote:

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

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

Many data types don't have a notion of distance, but still define a total
ordering, which I think was the original point. What would be the distance
between two strings? If "ab" < "abc", what is the distance between them?
Even though the empty string is the multiplicative identity for strings,
it's not an "origin" from which other strings can be said to have a
distance from.

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

GitHub - midiguchi/midiguchi: midiguchi - MIDI I/O using Functional Reactive Programming with Bacon.js. Transpose, remap, filter, manipulate arbitrarily, or synthesize MIDI events with ease.

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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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

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

I can totally agree that it's not something to deal with Zero concept.

Though discussion was completely lost for another use case of _generic
factories_.

Also, the interesting part is that discussion brought us to the question if
Bool.init(), Int.init() and alike should be removed. I'm 100% positive here
as it brings a lot of uncertainty.

In general, I think if we remove inits described above,
DefaultConstructable will be more appealing. I don't see it as a Zero, but
rather as a default factory.

Best,
Daniel

···

On Tue, 27 Dec 2016 at 3:30 Adam Nemecek via swift-evolution < swift-evolution@swift.org> wrote:

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

GitHub - midiguchi/midiguchi: midiguchi - MIDI I/O using Functional Reactive Programming with Bacon.js. Transpose, remap, filter, manipulate arbitrarily, or synthesize MIDI events with ease.

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

>>>

>>>

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

>>>

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

>>>

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

>>> <Failable Initializers - Swift Blog - Apple Developer

>>> <Failable Initializers - Swift Blog - Apple Developer;

>>>

>>>

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

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

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

Even though the empty string is the multiplicative identity for strings,

it's not an "origin" from which other strings can be said to have a
distance from.

Imagination is the limit. You can create a sequence of string permutations
and assign integers to each permutation. Distance between "ab" and "abc" is
the same as the distance between their permutation numbers. Whether this
distance makes sense for strings is another question. You start with empty
string. Did this mode the discussion forward? I don't think it did.

···

On Mon, Dec 26, 2016 at 2:13 PM, Tony Allevato <tony.allevato@gmail.com> wrote:

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

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

Many data types don't have a notion of distance, but still define a total
ordering, which I think was the original point. What would be the distance
between two strings? If "ab" < "abc", what is the distance between them?
Even though the empty string is the multiplicative identity for strings,
it's not an "origin" from which other strings can be said to have a
distance from.

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

GitHub - midiguchi/midiguchi: midiguchi - MIDI I/O using Functional Reactive Programming with Bacon.js. Transpose, remap, filter, manipulate arbitrarily, or synthesize MIDI events with ease.

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 :)
>>>
>>>
>>> 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 ;)
>>>
>>> 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 :)
>>>
>>> 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."
>>> <Failable Initializers - Swift Blog - Apple Developer
>>> <Failable Initializers - Swift Blog - Apple Developer;
>>>
>>>
>>> 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

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

+1

Why? well… that is difficult. Mainly because it “feels” right.
Having read a lot of the discussion (but not all) it seems impossible to make a “must have” case for it. But on a more conceptual level this feels similar to the discovery of zero in mathematics.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: Swiftrien (Rien) · GitHub
Project: http://swiftfire.nl

···

On 27 Dec 2016, at 04:01, Daniel Leping via swift-evolution <swift-evolution@swift.org> wrote:

I can totally agree that it's not something to deal with Zero concept.

Though discussion was completely lost for another use case of _generic factories_.

Also, the interesting part is that discussion brought us to the question if Bool.init(), Int.init() and alike should be removed. I'm 100% positive here as it brings a lot of uncertainty.

In general, I think if we remove inits described above, DefaultConstructable will be more appealing. I don't see it as a Zero, but rather as a default factory.

Best,
Daniel

On Tue, 27 Dec 2016 at 3:30 Adam Nemecek via swift-evolution <swift-evolution@swift.org> wrote:
> 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.

GitHub - midiguchi/midiguchi: midiguchi - MIDI I/O using Functional Reactive Programming with Bacon.js. Transpose, remap, filter, manipulate arbitrarily, or synthesize MIDI events with ease.

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

>>>

>>>

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

>>>

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

>>>

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

>>> <Failable Initializers - Swift Blog - Apple Developer

>>> <Failable Initializers - Swift Blog - Apple Developer;

>>>

>>>

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

_______________________________________________

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

-1

1) There is no semantic meaning to empty initializers.

2) It is a simple protocol to create and apply for specific (and semantically meaningful) purposes

3) This would be a core protocol and I defer to the team. when it comes to low-level protocols. This seems to be in conflict with their vision. There are already concrete solutions for potential uses (e.g. Initializing Arrays).

- Chris K

···

On Dec 27, 2016, at 12:52 AM, Rien via swift-evolution <swift-evolution@swift.org> wrote:

+1

Why? well… that is difficult. Mainly because it “feels” right.
Having read a lot of the discussion (but not all) it seems impossible to make a “must have” case for it. But on a more conceptual level this feels similar to the discovery of zero in mathematics.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: Swiftrien (Rien) · GitHub
Project: http://swiftfire.nl

On 27 Dec 2016, at 04:01, Daniel Leping via swift-evolution <swift-evolution@swift.org> wrote:

I can totally agree that it's not something to deal with Zero concept.

Though discussion was completely lost for another use case of _generic factories_.

Also, the interesting part is that discussion brought us to the question if Bool.init(), Int.init() and alike should be removed. I'm 100% positive here as it brings a lot of uncertainty.

In general, I think if we remove inits described above, DefaultConstructable will be more appealing. I don't see it as a Zero, but rather as a default factory.

Best,
Daniel

On Tue, 27 Dec 2016 at 3:30 Adam Nemecek via swift-evolution <swift-evolution@swift.org> wrote:

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.

GitHub - midiguchi/midiguchi: midiguchi - MIDI I/O using Functional Reactive Programming with Bacon.js. Transpose, remap, filter, manipulate arbitrarily, or synthesize MIDI events with ease.

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

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

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

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

<Failable Initializers - Swift Blog - Apple Developer

<Failable Initializers - Swift Blog - Apple Developer;

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

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

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

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

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