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