On Mon, Dec 26, 2016 at 1:59 PM 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? > 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. > > 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
