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
