decided to play with a different syntax https://gist.github.com/lmihalkovic/8aa66542f5cc4592e967bade260477ef
still have to formalize it, but it does work for many situations, and is consistent with var a: P1 & P2 > On Jun 9, 2016, at 6:44 PM, Dave Abrahams via swift-evolution > <swift-evolution@swift.org> wrote: > > > on Thu Jun 09 2016, Douglas Gregor <dgregor-AT-apple.com> wrote: > >>> On Jun 8, 2016, at 11:57 AM, Dave Abrahams via swift-evolution >> <swift-evolution@swift.org> wrote: >>> >>> >>> on Sun Jun 05 2016, Douglas Gregor <swift-evolution@swift.org >> <mailto:swift-evolution@swift.org>> wrote: >>> >> >>>> Sent from my iPhone >>>> >>>>> On Jun 5, 2016, at 6:41 PM, Matthew Johnson <matt...@anandabits.com> >>>>> wrote: >>>>> >>>>> >>>>> >>>>> Sent from my iPad >>>>> >>>>>> On Jun 5, 2016, at 6:20 PM, Douglas Gregor <dgre...@apple.com> wrote: >>>>>> >>>>>> >>>>>>> On May 18, 2016, at 12:35 AM, Austin Zheng <austinzh...@gmail.com> >>>>>>> wrote: >>>>>>> >>>>>>> I've put together a considerably more detailed draft proposal, >>>>>>> taking into account as much of Matthew's feedback as I could. You >>>>>>> can find it below: >>>>>>> >>>>>>> https://github.com/austinzheng/swift-evolution/blob/az-existentials/proposals/XXXX-enhanced-existentials.md >>>>>>> >>>>>>> Since there is no chance this will come up for review anytime >>>>>>> soon, I expect to make significant revisions to it over the next >>>>>>> month or so. Any feedback would be greatly appreciated. >>>>>> >>>>>> This is very much Swift 4 territory, but I can’t help myself… so… >>>>>> >>>>>> The actual feature description is spread out through this very long >>>>>> document, with user-facing ideas (e.g., using “anonymous associated >>>>>> types”) intermixed with deeper technical details (existential type >>>>>> equivalence), so it’s very daunting to read. Please bring the >>>>>> user-facing features to the front (“Proposed Solution”) with >>>>>> examples, and save the deeper technical details for “Detailed >>>>>> Design”. You want more readers to make it through the part that >>>>>> affects them. >>>>>> >>>>>> Shortcut 'dot' notation: If there is only one protocol with >>>>>> associated types specified in the requirements, and there are no >>>>>> nested Any<...> requirements with where clauses of their own, that >>>>>> protocol's name can be omitted from the whereclause constraints: >>>>>> >>>>>> // Okay >>>>>> // Would otherwise be Any< ~ where Collection.Element == Int> >>>>>> let a : Any<class, Collection, Any<Streamable, CustomStringConvertible> >>>>>> where .Element == Int> >>>>>> >>>>>> // NOT ALLOWED >>>>>> // Both Collection and OptionSetType have associated types. >>>>>> let b : Any<Collection, OptionSetType where .Element == Int> >>>>>> FWIW, I think “.Element == Int” should be the only syntax. In >>>>>> generic signatures, if you have two different protocols with >>>>>> same-named associated types, and a given type parameter (or >>>>>> associated type) conforms to both protocols, the associated types >>>>>> are (implicitly) made equivalent via an inferred same-type >>>>>> constraint. So there’s no reason to introduce the >>>>>> “Collection.Element == Int” syntax, because the “Collection” part >>>>>> is basically irrelevant. >>>>>> >>>>>> Once existentials have been suitably enhanced, there is a strong >>>>>> analogy between an existential and a generic signature with a >>>>>> single type parameter that you can’t name. An existential >>>>>> Any<Collection where .Element : Equatable> has most of the same >>>>>> characteristics as a generic something with the signature <T : >>>>>> Collection where T.Element : Equatable>. Specifically, the sections >>>>>> on “Existential type equivalence”, “Ordering”, “Real types to >>>>>> anonymous associated types”, “Anonymous associated types to real >>>>>> types”. could be reduced to a few small, simple examples and a >>>>>> mention of the analogous behavior of generics. It will be far >>>>>> easier to explain this way, and readers don’t need to get immersed >>>>>> in the details. Where there are differences vs. generics, that’s >>>>>> important to point out. >>>>>> >>>>>> “Associated typealias rewriting”: this also falls out of the equivalence >>>>>> with generics + SE-0092. >>>>>> >>>>>> “Associated types and member exposure”: you don’t make the point >>>>>> that it only makes sense to refer to the associated types of a let >>>>>> constant; a var could change its type dynamically, which would >>>>>> invalidate the typing rules. Did you consider just using >>>>>> “x.dynamicType” in the type grammar for this? It’s more general, in >>>>>> that you can refer to associated types but also talk about the >>>>>> dynamic type of “x” itself, e.g., >>>>>> >>>>>> let x: Equatable = … >>>>>> let y: Equatable = … >>>>>> if let yAsX = y as? x.dynamicType { … x == yAsX … } >>>>>> >>>>>> which is (almost?) as powerful as a general “open” expression. >>>>>> >>>>>> I’m not a fan of the “anonymous associated types” terminology: >>>>>> these are associated types of a type of some runtime-defined >>>>>> value. The only thing “anonymous” about them is that it’s harder to >>>>>> spell the base type; otherwise, they’re just like associated types >>>>>> of a generic type parameter. Again, the generics analogy is strong >>>>>> here. >>>>>> >>>>>> FWIW, I don’t think we’ll ever need “opening existentials” with >>>>>> what you’ve described here. Also, remember that a method of a >>>>>> protocol extension essentially opens “Self”, so we already have one >>>>>> way to open an existential (and that’s probably enough). >>>>>> >>>>>> I was a little surprised you didn’t point out that AnyObject could become >>>>>> >>>>>> typealias AnyObject = Any<class> >>>>>> >>>>>> or give the nice “AnyCollection” syntax: >>>>>> >>>>>> typealias AnyCollection<T> = Any<Collection where .Element == T> >>>>>> >>>>>> the latter of which is fairly important, because it gives nice >>>>>> syntactic sure to one of the most highly-requested features >>>>>> [*]. I’d suggest having that example very, very early. >>>>>> >>>>>> - Doug >>>>>> >>>>>> [*] That generally comes in as “Swift should have parameterized >>>>>> protocols…” >>>>> >>>>> Great feedback here Doug. >>>>> >>>>> FWIW, we also occasionally get "Swift should have parameterized >>>>> protocols" in the context of multiple conformances by the same >>>>> concrete type (as in things like ConvertibleTo<T> protocol). >>>> >>>> I know. From the bugs I've seen it's at least 10x as many requests for >>>> "any collection of some element type" as for any actually reason why >>>> one would need parameterize a protocols. >>> >>> That does, however, speak for the idea that a concise and obvious >> syntax >>> should be supported for that use-case. >>> >>> Personally, it doesn't seem ridiculous to me that some associated >> types >>> might usefully be written as type parameters on a protocol. As >>> Collection shows, not all associated types are equally important. >>> Approximately nobody wants the existential “Collection where Index >> == >>> Int.” >> >> I’ve toyed with some form of this idea before, and IIRC it was >> discussed on this list at one point, where some or all associate types >> move up to the “type parameter” position in the grammar, e.g., >> >> protocol Collection<Element> : Sequence<Element> { >> associatedtype Index >> associatedtype SubSequence >> } >> >> However, unless that is semantically a type parameter in the sense >> that one can have a single concrete type conform to Collection<A> and >> Collection<B> separately, I think it’s misleading to go this route, >> even if it does give us the clean “Collection<Int>” syntax. > > Excellent point! I hadn't considered it. > > -- > Dave > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution