<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="">an alternative to the Any<> syntax with tentative grammar and some examples (still a WIP)</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><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 6, 2016, at 1:20 AM, Douglas Gregor 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=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On May 18, 2016, at 12:35 AM, Austin Zheng <<a href="mailto:austinzheng@gmail.com" class="">austinzheng@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">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:<div class=""><br class=""></div><div 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=""></div><div class=""><br class=""></div><div class="">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.</div></div></div></blockquote><div class=""><br class=""></div><div class="">This is very much Swift 4 territory, but I can’t help myself… so…</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><span style="box-sizing: border-box;" class="">Shortcut 'dot' notation</span>: If there is only one protocol with associated types specified in the requirements, and there are no nested <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Any<...></code> requirements with <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">where</code> clauses of their own, that protocol's name can be omitted from the <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">where</code>clause constraints:</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Okay</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Would otherwise be Any< ~ where Collection.Element == Int></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> a <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span>, Collection, <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Streamable</span>, <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">CustomStringConvertible</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">where</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>Element <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">==</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// NOT ALLOWED</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// Both Collection and OptionSetType have associated types.</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> b <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Collection, <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">OptionSetType</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">where</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">.</span>Element <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">==</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span></pre></div><div class="">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.</div><div class=""><br class=""></div></div><div class="">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.</div><div class=""><br class=""></div><div class="">“Associated typealias rewriting”: this also falls out of the equivalence with generics + SE-0092.</div><div class=""><br class=""></div><div class="">“Associated types and member exposure”: you don’t make the point that it only makes sense to refer to the associated types of a <b class="">let</b> constant; a <b class="">var</b> 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.,</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let x: Equatable = …</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let y: Equatable = …</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>if let yAsX = y as? x.dynamicType { … x == yAsX … }</font></div><div class=""><br class=""></div><div class="">which is (almost?) as powerful as a general “open” expression.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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).</div><div class=""><br class=""></div><div class="">I was a little surprised you didn’t point out that AnyObject could become</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>typealias AnyObject = Any<class></font></div><div class=""><br class=""></div><div class="">or give the nice “AnyCollection” syntax:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>typealias AnyCollection<T> = Any<Collection where .Element == T></font></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div class=""><br class=""></div><div class="">[*] That generally comes in as “Swift should have parameterized protocols…”</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">Austin</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, May 17, 2016 at 9:52 PM, Austin Zheng <span dir="ltr" class=""><<a href="mailto:austinzheng@gmail.com" target="_blank" class="">austinzheng@gmail.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote"><span class="">On Tue, May 17, 2016 at 1:25 PM, Matthew Johnson <span dir="ltr" class=""><<a href="mailto:matthew@anandabits.com" target="_blank" class="">matthew@anandabits.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class=""><br class=""></div><div class="">Within the angle brackets are zero or more 'clauses'. Clauses are separated by semicolons. (This is so commas can be used in where constraints, below. Better ideas are welcome. Maybe it's not necessary; we can use commas exclusively.)</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I’m not a fan of the semicolon idea. I don’t see any reason for this. The `where` keyword separates the protocol list from the constraints just fine. The list on either side should be able to use commas with no problem (or line breaks if that proposal goes through).</div><span class=""><br class=""></span></div></div></blockquote><div class=""><br class=""></div><div class="">I'm leaning towards getting rid of the commas, but would like to write out a few 'dummy' examples to see if there are any readability issues that arise. <br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Replaced with what? Whitespace separation? I suppose that might work for the protocol list but it feels inconsistent with the rest of Swift. Commas plus (hopefully) the alternative of newline seem like the right direction to me.</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Sorry, I completely misspoke (mistyped?). I meant I want to get rid of the semicolons and use commas. I've come to the conclusion that there are no readability issues, protocol<> already uses commas, and semicolons used in this manner don't have a precedent anywhere else in the language.</div><span class=""><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class=""><br class=""></div><div class="">There are five different possible clauses:</div><div class=""><br class=""></div><div class=""><ul class=""><li class="">'class'. Must be the first clause, if present. Places a constraint on the existential to be any class type. (Implies: Only one can exist. Mutually exclusive with class name clause.)<br class=""></li></ul></div><div class=""><br class=""></div><div class="">(In the future a follow-up proposal should add in 'struct' or 'value' as a counterpart.)</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">If we’re going to allow `struct` we should also allow `enum`. `value` would allow either of those.</div><span class=""><br class=""></span></div></div></blockquote><div class=""><br class=""></div><div class="">Of course. A future proposal can allow list members to discuss the exact details as to how struct, value, or enum specifiers should work. <br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Yep, agree. Just mentioning that if we’re going to reference it we should not leave obvious holes in what would be considered. :)</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Absolutely.</div><span class=""><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class=""><br class=""></div><div class=""><ul class=""><li class="">Class name. Must be the first clause, if present. (Implies: Only one can exist. Mutually exclusive with 'class'.) Places a constraint on the existential (not really an existential anymore) to be an instance of the class, or one of its subclasses.<br class=""></li></ul></div></div></div></div></div></blockquote></span><div class="">It is still be an existential if it includes protocol requirements that the class does not fulfill. For example, you might have Any<UIView, SomeProtocol> where UIView does not conform to SomeProtocol, but various subclasses do.</div><div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">Fair enough. (I don't think the way things work would be affected.)</div><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""></div><div class="">Your proposal doesn’t discuss composing Any in the way that Adrian’s did like this:</div><div class=""><br class=""></div><div class="">typealias Foo = Any<SomeClass, SomeProtocol, OtherProtocol></div><div class="">Any<AnotherProtocol, Foo></div></div></div></blockquote><div class=""><br class=""></div><div class="">I didn't think it needed to be discussed. An Any<...> existential type is a type 'expression' just like any other, and should be allowed to participate in other Any<...>s.</div></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div><div class="">I like the idea of composition as it allows us to factor out constraints. If we are going to do that we should allow a class to be specified in the composition as long is it is a subclass of all class requirements of Any types it composes. For example, this should be allowed:</div><div class=""><br class=""></div><div class="">typealias Bar = Any<SubclassOfSomeClass, Foo, AnotherProtocol></div><div class=""><br class=""></div><div class="">This is still one class requirement for Bar, it just refines the class requirement of Foo to be SubclassOfSomeClass rather than just SomeClass.</div></div></div></blockquote><div class=""><br class=""></div><div class="">This is a good point. There should be clarification as to how special cases of Any<...> used in another Any<...> behave. For example, like you said Any<MyClass, Any<SomeSubclassOfMyClass, Protocol>> should be valid. This will go into any proposal that emerges from the discussion.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Yes, this is why we need to discuss Any composition. There are also cases of incompatible associated type constraints which need to be rejected (such as composing two Any’s where one has Element == String and another has Element == Int).</div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class="">Example: Any<UIViewController; UITableViewDataSource; UITableViewDelegate></div><div class="">"Any UIViewController or subclass which also satisfies the table view data source and delegate protocols"</div><div class=""><ul class=""><li class="">Dynamic protocol. This is entirely composed of the name of a protocol which has no associated types or Self requirement.</li></ul></div></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class="">Example: Any<CustomStringConvertible; BooleanType></div><div class="">"Any type which conforms to both the CustomStringConvertible and BooleanType protocols"</div><div class=""><br class=""></div><div class="">I'm going to use 'static protocol' to refer to a protocol with associated types or self requirements. Feel free to propose a more sound name.</div><div class=""><br class=""></div><div class=""><ul class=""><li class="">Self-contained static protocol, simple. This is composed of the name of a static protocol, optionally followed by a 'where' clause in which the associated types can be constrained (with any of the three basic conformance types: subclassing, protocol conformance, or type equality). Associated types are referred to with a leading dot.<br class=""></li></ul></div></div></div></div></div></blockquote></span><div class="">Please do not introduce terms “dynamic protocol” and “static protocol”. We want to support existentials of protocols that have self or associated type requirements. The dynamic vs static distinction is a limitation of the current implementation of Swift and doesn’t make sense for the long term vision.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I'm not trying to introduce new terms, these are just placeholders. At the same time "protocols with self or associated type requirements" is cumbersome to work with and it would be nice for someone to come up with a descriptive term of art for referring to them.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I agree that a better term would be useful. In the meantime, I would prefer something like “trivial” and “nontrivial” protocols.</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I've decided to just use the full name until the community comes up with better names. Clarity is preferable to brevity in this case.</div><span class=""><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><span class=""><div class=""><br class=""></div><div class="">Example: Any<Collection where .Generator.Element : NSObject, .Generator.Element : SomeProtocol></div></span><div class="">"Any type that is a Collection, whose elements are NSObjects or their subclasses conforming to SomeProtocol.”</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Swift does not allow disjunction of requirements. Only conjunctions are supported. That means the correct reading is:</div><div class=""><br class=""></div><div class="">"Any type that is a Collection, whose elements are NSObjects<span class=""> </span><b class="">and</b><span class=""> </span>their subclasses conforming to SomeProtocol.”</div><br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">Yes, that is what I meant. "whose elements are (NSObjects or their subclasses) conforming to SomeProtocol”.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Ok, good. Wasn’t quite clear to me.</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Yes, the verbiage will need to be clearer in the future. That sentence could be ambiguously parsed.</div><span class=""><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><span class=""><div class=""><br class=""></div><div class=""><ul class=""><li class="">Bound static protocol. This is the same as a self-contained static protocol, but with a leading "<name> as " which binds the protocol to a generic typealias. The name can be then be used in subsequent clauses to build constraints.<br class=""></li></ul></div><div class=""><br class=""></div><div class="">Example: Any<T as Collection; IntegerLiteralConvertible where .IntegerLiteralType == T.Element>.</div></span><div class="">"Any type that is a Collection, and also can be built from an integer literal, in which the collection elements are the same type as the type of the integer used for the integer literal conformance.”</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I’m not sure about this, but if we’re going to do it it should be the other way around: `Collection as T` with the alias<span class=""> </span><i class="">after</i> the name of the protocol. </div><div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">I like this, it flows better. "Protocol as T where Protocol.Foo == Int, Protocol.Bar : Baz”.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Why did you introduce an alias here and then not use it? Did you mean "Protocol as T where T.Foo == Int, T.Bar : Baz"</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Another result of rushing to compose an email. Sorry!</div><span class=""><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class=""></div><div class="">You are also using “dot shorthand” here to refer to an associated type of IntegerLiteralConvertible. I think “dot shorthand” should be limited to cases where there is only one protocol that is getting constrained. In other cases, we need to be clear about which protocol we are referring to.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I borrowed dot shorthand from the generics manifesto. But you are right, it should only be allowed if there is one protocol with associated types or self requirements clause in the Any<...> construction.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I would actually go further and limit it to one protocol period, and possibly even to one protocol and no type names (as types can have nested types and typealiases). When we allow shorthand it should be immediately unambiguous what the shorthand references with no need to look at type or protocol declarations.</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">It might be desirable to propose the proposal with no allowance for shorthand, and have the dot shorthand be a smaller follow-up proposal.</div><span class=""><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class=""><br class=""></div><div class="">There will be rules to prevent recursive nesting. For example, if generic typealiases are allowed, they cannot refer to each other in a circular manner (like how structs can't contain themeselves, and you can't create a cyclic graph of enums containing themselves).</div><div class=""><br class=""></div><div class="">How an existential can be used depends on what guarantees are provided by the clauses. For example, 'Any<Equatable>' can't be used for much; if there were any methods on Equatable that did not use the associated types at all you'd be able to call them, but that's about it. However, 'Any<Equatable where .Self == String>' would allow for == to be called on instances. (This is a stupid example, since Any<Equatable where .Self == String> is equivalent to 'String', but there are almost certainly useful examples one could come up with.)</div></div><div class=""><br class=""></div><div class="">In order of increasing 'power':</div><div class=""><ul class=""><li class="">Don't constrain any associated types. You can pass around Any<Equatable>s, but that's about it.</li><li class="">Constrain associated types to conform to protocols.</li><li class="">Fully constrain associated types.</li></ul></div></div></div></div></blockquote></span></div><div class="">I think we need to spell out pretty clearly what members we expect to be available or not available. This section probably needs the most design and elaboration. </div><div class=""><br class=""></div><div class="">For example, we probably can’t access a member who uses an associated type as an input unless it is constrained to a specific type. On the other hand output types probably don’t need to limit access to a member. However, if the output type is Self or an associated type the visible signature would have an output type which has the relevant constraints of the existential applied, but no more. In some cases this means the output type would simply be Any.</div></div></blockquote><div class=""><br class=""></div><div class="">Absolutely. This is vaguely what I had in mind but I wanted to get something down first. Thanks for thinking through some of the implications :).</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">That’s what I thought. Just wanted to start the process of elaborating expectations.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><span class=""><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">Where this really gets tricky is for compound types like functions, generic types, etc. Working out the details in these cases is pretty complex. I will defer to Doug on whether it is best to just defer those cases to the future, leave them up to the implementer, or try to work out all of the relevant details in the proposal (in which case we probably need a type system expert to help!).</div></div></blockquote><div class=""><br class=""></div></span><div class="">Yes, exactly! For example, can Any<...> existentials involving protocols with associated types or self requirements be used within generic function or type definitions? Maybe there's an argument that existential types of this nature are redundant if you have access to generics (e.g. defining a property on a generic type that is a Collection containing Ints; you should be able to do that today). On the other hand, maybe there are use cases I haven't thought of…</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I see no reason they shouldn’t be. They are not redundant at all. For example, you may want to store instances in a heterogeneous collection. You need existentials to do that.</div><div class=""><br class=""></div><div class="">A simple example of what I was referring to there is something like this:</div><div class=""><br class=""></div><div class="">protocol P {</div><div class=""> associatedtype Foo</div><div class=""><br class=""></div><div class=""> func bar(callback: (Foo) -> ())</div><div class="">}</div><div class=""><br class=""></div><div class="">In other words, types in the signature of a protocol member are complex types that reference Self or associated types. I think you really need a formal understanding of the type system to understand how to expose these members through a constrained existential. We can probably understand the expected behavior in some of the simpler cases on a case by case basis, but that approach doesn’t scale at all and is arbitrary. If they’re going to be supported an expert is going to need to be involved in the design.</div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Yes. I have some ideas regarding this topic.</div><span class=""><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">One area you didn’t touch on is “opening” the existential? Is that out of scope for this proposal? That would be fine with me as this proposal is already taking on a lot. But if so, you should mention something about future directions as it is pretty closely related to this proposal.</div></div></blockquote><div class=""><br class=""></div><div class="">Yes, existential opening is explicitly separate from this (although I wanted to mention it in the section where I talk about how Any<Equatable> is not very useful). But you are absolutely right, this proposal should discuss how it wants to interact with possible future directions.</div></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">Another area you didn’t touch on is whether Any constructs (and typealiases referring to them) should be usable as generic constraints. I would expect this to be possible but I think we need to spell it out.</div></div></blockquote><div class=""><br class=""></div><div class="">I'm hoping for community input. This is a tricky subject, and at some point we'll bump into implementation limitations.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I don’t think it’s too tricky. You can just unpack the constraints of the Any into the list of generic constraints. Maybe I’m missing something, but I don’t think so.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><span class=""><font color="#888888" class=""><div class=""><br class=""></div><div class="">-Matthew</div></font></span></div></blockquote></div></div></div></div></blockquote></div><br class=""></div></blockquote></span></div><br class=""></div></div>
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div>_______________________________________________<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></blockquote></div><br class=""></body></html>