[swift-evolution] [Pitch] Add the DefaultConstructible protocol to the standard library

Daniel Leping daniel at crossroadlabs.xyz
Mon Dec 26 21:01:26 CST 2016


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 at 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.
>
> https://github.com/midiguchi/midiguchi
>
> Do you see the zip operation? Could you tell me what it does? Note that I
> have no relationship to this project. I can find more if I really try. So
> now there is a precedence, so what's next? Are you going to tell me that
> this doesn't count? Why not?  I was aware of this library even before this
> discussion btw.
>
> > No, I mean that you are incorrect.
>
> Well if you say so it must be true. Lol.
>
> > What closure property? My question was, why are you not using
> `Strideable`? You are describing its semantics. I'm not sure what closure
> you are referring to.
>
> Algebraic closure.
>
> > As I explained earlier, your argument _is_ circular. But it's clear now
> you will not accept that being point out to you by multiple people
> independently.
>
> It's not circular, it's I use data point to point out that this is a
> common pattern.
>
>
>
> On Mon, Dec 26, 2016 at 1:43 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> On Mon, Dec 26, 2016 at 4:28 PM, 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.
>
>
> 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 at gmail.com> wrote:
>
> On Mon, Dec 26, 2016 at 1:50 PM, Adam Nemecek via swift-evolution <
> swift-evolution at 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 at swift.org> wrote:
>
>
>
>
> on Mon Dec 26 2016, Jonathan Hull <swift-evolution at 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 at 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 at gbis.com <mailto:jhull at 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 at swift.org
>
>
> >>> <mailto:swift-evolution at 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 at gmail.com
>
>
> >>> <mailto:xiaodi.wu at gmail.com>> wrote:
>
>
> >>> On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping
>
>
> >>> <daniel at crossroadlabs.xyz
>
>
> >>> <mailto:daniel at 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 at gmail.com
>
>
> >>> <mailto:xiaodi.wu at gmail.com>> wrote:
>
>
> >>> On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping
>
>
> >>> <daniel at crossroadlabs.xyz
>
>
> >>> <mailto:daniel at 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 at gmail.com
>
>
> >>> <mailto:xiaodi.wu at gmail.com>> wrote:
>
>
> >>> On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping
>
>
> >>> <daniel at crossroadlabs.xyz
>
>
> >>> <mailto:daniel at 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 at gmail.com
>
>
> >>> <mailto:xiaodi.wu at gmail.com>> wrote:
>
>
> >>> On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping
>
>
> >>> <daniel at crossroadlabs.xyz
>
>
> >>> <mailto:daniel at crossroadlabs.xyz>>
>
>
> >>> wrote:
>
>
> >>> I'm giving a wider range, which is about ANY factory pattern
>
>
> >>> related stuff. Doesn't look to be narrow to me.
>
>
> >>>
>
>
> >>> I thought factory methods were regarded as undesirable in Swift?
>
>
> >>> One of the stated reasons for failable initializers was: "Failable
>
>
> >>> initializers eliminate the most common reason for factory methods
>
>
> >>> in Swift... Using the failable initializer allows greater use of
>
>
> >>> Swift’s uniform construction syntax, which simplifies the language
>
>
> >>> by eliminating the confusion and duplication between initializers
>
>
> >>> and factory methods."
>
>
> >>> <https://developer.apple.com/swift/blog/?id=17
>
>
> >>> <https://developer.apple.com/swift/blog/?id=17>>
>
>
> >>>
>
>
> >>>
>
>
> >>> On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu
>
>
> >>> <xiaodi.wu at gmail.com
>
>
> >>> <mailto:xiaodi.wu at gmail.com>> wrote:
>
>
> >>> On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping
>
>
> >>> <daniel at crossroadlabs.xyz
>
>
> >>> <mailto:daniel at 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 at gmail.com
>
>
> >>> <mailto:xiaodi.wu at gmail.com>> wrote:
>
>
> >>> On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping
>
>
> >>> <daniel at crossroadlabs.xyz
>
>
> >>> <mailto:daniel at 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 at gmail.com
>
>
> >>> <mailto:xiaodi.wu at gmail.com>> wrote:
>
>
> >>> On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution
>
>
> >>> <swift-evolution at swift.org
>
>
> >>> <mailto:swift-evolution at 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 at swift.org
>
>
> >>> <mailto:swift-evolution at swift.org>>
>
>
> >>> wrote:
>
>
> >
>
>
> > _______________________________________________
>
>
> > swift-evolution mailing list
>
>
> > swift-evolution at swift.org
>
>
> > https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> >
>
>
>
>
>
> --
>
>
> -Dave
>
>
>
>
>
> _______________________________________________
>
>
> swift-evolution mailing list
>
>
> swift-evolution at swift.org
>
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
>
> _______________________________________________
>
>
> swift-evolution mailing list
>
>
> swift-evolution at swift.org
>
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
>
> swift-evolution mailing list
>
> swift-evolution at swift.org
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161227/3fcf0a20/attachment.html>


More information about the swift-evolution mailing list