<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 8, 2016, at 11:57 AM, Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">on Sun Jun 05 2016, Douglas Gregor &lt;</span><a href="mailto:swift-evolution@swift.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">swift-evolution@swift.org</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">&gt; wrote:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Sent from my iPhone<br class=""><br class=""><blockquote type="cite" class="">On Jun 5, 2016, at 6:41 PM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; 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 &lt;<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>&gt; wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class="">On May 18, 2016, at 12:35 AM, Austin Zheng &lt;<a href="mailto:austinzheng@gmail.com" class="">austinzheng@gmail.com</a>&gt; 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&lt;...&gt; 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&lt; ~ where Collection.Element == Int&gt;<br class="">let a : Any&lt;class, Collection, Any&lt;Streamable, CustomStringConvertible&gt; where .Element == Int&gt;<br class=""><br class="">// NOT ALLOWED<br class="">// Both Collection and OptionSetType have associated types.<br class="">let b : Any&lt;Collection, OptionSetType where .Element == Int&gt;<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&lt;Collection where .Element : Equatable&gt; has most of the same<br class="">characteristics as a generic something with the signature &lt;T :<br class="">Collection where T.Element : Equatable&gt;. 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&lt;class&gt;<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&lt;T&gt; = Any&lt;Collection where .Element == T&gt;<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&lt;T&gt; 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 style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">That does, however, speak for the idea that a concise and obvious syntax</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">should be supported for that use-case.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Personally, it doesn't seem ridiculous to me that some associated types</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">might usefully be written as type parameters on a protocol. &nbsp;As</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Collection shows, not all associated types are equally important.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Approximately nobody wants the existential “Collection where Index ==</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Int.”</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote></div><div class=""><br class=""></div><div class="">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.,</div><div class=""><br class=""></div><div class="">protocol Collection&lt;Element&gt; : Sequence&lt;Element&gt; {</div><div class="">&nbsp; associatedtype Index</div><div class="">&nbsp; associatedtype SubSequence</div><div class="">}</div><div class=""><br class=""></div><div class="">However, unless that is semantically a type parameter in the sense that one can have a single concrete type conform to Collection&lt;A&gt; and Collection&lt;B&gt; separately, I think it’s misleading to go this route, even if it does give us the clean “Collection&lt;Int&gt;” syntax.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div class=""><br class=""></div></body></html>