<div dir="ltr"><div> On Wed, Mar 2, 2016 at 5:22 PM, Douglas Gregor via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:</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"><div></div><div><br></div><div><i style="font-size:14px">Opening existentials</i></div><div><br></div><div>Generalized existentials as described above will still have trouble with protocol requirements that involve Self or associated types in function parameters. For example, let’s try to use Equatable as an existential:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="Menlo">protocol Equatable {</font></div><div><font face="Menlo">  func ==(lhs: Self, rhs: Self) -&gt; Bool</font></div><div><font face="Menlo">  func !=(lhs: Self, rhs: Self) -&gt; Bool</font></div><div><font face="Menlo">}</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">let e1: Equatable = …</font></div><div><font face="Menlo">let e2: Equatable = …</font></div><div><font face="Menlo">if e1 == e2 { … } <i>// <b>error</b>:</i> e1 and e2 don’t necessarily have the same dynamic type</font></div></blockquote><div><br></div><div>One explicit way to allow such operations in a type-safe manner is to introduce an “open existential” operation of some sort, which extracts and gives a name to the dynamic type stored inside an existential. For example:</div><div><br></div><div><span style="white-space:pre-wrap">        </span> </div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="Menlo">if let storedInE1 = e1 openas T {     // T is a the type of storedInE1, a copy of the value stored in e1</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="Menlo">  if let storedInE2 = e2 as? T {      // is e2 also a T?</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="Menlo">    if storedInE1 == storedInE2 { … } // okay: storedInT1 and storedInE2 are both of type T, which we know is Equatable</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="Menlo">  }</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="Menlo">}</font></blockquote></div><div><br></div><div><br></div></div></blockquote><div><br></div><div>Any chance we could have the as? operator used for opening existentials instead of introducing a new openas one?</div><div><br></div><div>My reasoning is that the usage for opening an existential is very similar to the usage for downcasting to a subtype.  In both cases, the initial variable may be one of a large number of possible values, and you are conditionally testing for membership in a subset of those values.  With the downcast, the subset is a subtype.  With the existential, the subset is a single type in the type family.  Indeed, in many cases your &quot;test for a concrete type conforming to a protocol&quot; became a &quot;test for a dynamic type in an existential&quot; because you added an associated type or Self reference to your protocol.  Syntactically, the rest of your program is identical.</div><div><br></div><div>I don&#39;t <i>think</i> there&#39;s any chance for ambiguity here: right now, you can&#39;t even create a value of type Equatable (since it can only be used as a generic constraint), so these are completely disjoint situations.</div><div><br></div><div>It&#39;d also be neat if there was a standard library function for &quot;if two objects are the same type and both equatable, compare with ==.  Otherwise, return false.&quot;  This seems to be by far the most common definition of .equals in languages in languages that let you override it (Java, Python, etc.)  Maybe as a default method on Equatable?</div><div><br></div><div>As a side note, will existentials mean that <a href="http://stackoverflow.com/questions/29278624/pure-swift-set-with-protocol-objects">protocols can finally be useful in Sets</a>?  Since Set requires that its element be Hashable yet adopting Hashable requires that the protocol can only be used as a generic constraint, you can&#39;t really put a bunch of objects all conforming to a protocol in a Set and do anything useful with them.  This is a really common pattern for eg. having a bunch of objects that all do something and wanting to apply all of their effects.</div></div>