+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: http://github.com/Swiftrien Project: http://swiftfire.nl > On 27 Dec 2016, at 04:01, Daniel Leping via swift-evolution > <[email protected]> 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 > <[email protected]> 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 <[email protected]> wrote: > On Mon, Dec 26, 2016 at 4:28 PM, Adam Nemecek <[email protected]> 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 <[email protected]> wrote: > On Mon, Dec 26, 2016 at 1:50 PM, Adam Nemecek via swift-evolution > <[email protected]> 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 > <[email protected]> wrote: > > > > on Mon Dec 26 2016, Jonathan Hull <[email protected]> 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 <[email protected]> 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 > > > >> <[email protected] <mailto:[email protected]>> 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 > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> wrote: > > > >>> > > > >>> It's not a matter of probability, but rather of certainty. Please. > > > >>> > > > >>> On Mon, 26 Dec 2016 at 12:56 Xiaodi Wu > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> wrote: > > > >>> On Mon, Dec 26, 2016 at 2:19 AM, Daniel Leping > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> 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 > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> wrote: > > > >>> On Mon, Dec 26, 2016 at 1:48 AM, Daniel Leping > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> 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 > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> wrote: > > > >>> On Mon, Dec 26, 2016 at 1:21 AM, Daniel Leping > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> 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 > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> wrote: > > > >>> On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> 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 > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> wrote: > > > >>> On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> 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 > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> wrote: > > > >>> On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> 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 > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> wrote: > > > >>> On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> 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 > > > >>> <[email protected] > > > >>> <mailto:[email protected]>> > > > >>> wrote: > > > > > > > > _______________________________________________ > > > > swift-evolution mailing list > > > > [email protected] > > > > https://lists.swift.org/mailman/listinfo/swift-evolution > > > > > > > > > > -- > > > -Dave > > > > > > _______________________________________________ > > > swift-evolution mailing list > > > [email protected] > > > https://lists.swift.org/mailman/listinfo/swift-evolution > > > > > > > _______________________________________________ > > > swift-evolution mailing list > > > [email protected] > > > https://lists.swift.org/mailman/listinfo/swift-evolution > > > > > > > > > > > > > > > > _______________________________________________ > > swift-evolution mailing list > > [email protected] > > https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
