<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 7, 2016, at 7:51 PM, 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=""><div class=""><br class="">on Tue Jun 07 2016, Matthew Johnson &lt;<a href="http://matthew-at-anandabits.com" class="">matthew-AT-anandabits.com</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">On Jun 6, 2016, at 12:22 AM, Dave Abrahams &lt;<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>&gt;<br class=""></blockquote>wrote:<br class=""><blockquote type="cite" class=""><br class=""><br class="">on Sun Jun 05 2016, Matthew Johnson &lt;<a href="http://matthew-at-anandabits.com" class="">matthew-AT-anandabits.com</a><br class=""></blockquote>&lt;<a href="http://matthew-at-anandabits.com/" class="">http://matthew-at-anandabits.com/</a>&gt;&gt; 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 3:51 PM, Dave Abrahams via swift-evolution<br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class="">on Wed May 25 2016, Matthew Johnson &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">Sent from my iPad<br class=""><br class=""><blockquote type="cite" class="">On May 25, 2016, at 12:10 PM, Jordan Rose via swift-evolution<br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">On May 25, 2016, at 05:27, Brent Royal-Gordon via swift-evolution<br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">AFAIK an existential type is a type T with type parameters that<br class="">are still abstract (see for example<br class=""><a href="https://en.wikipedia.org/wiki/Type_system#Existential_types" class="">https://en.wikipedia.org/wiki/Type_system#Existential_types</a>),<br class="">i.e. have not been assigned concrete values.<br class=""></blockquote><br class="">My understanding is that, in Swift, the instance used to store<br class="">something whose concrete type is unknown (i.e. is still abstract),<br class="">but which is known to conform to some protocol, is called an<br class="">"existential". Protocols with associated values cannot be packed<br class="">into normal existentials because, even though we know that the<br class="">concrete type conforms to some protocol, the associated types<br class="">represent additional unknowns, and Swift cannot be sure how to<br class="">translate uses of those unknown types into callable members. Hence,<br class="">protocols with associated types are sometimes called<br class="">"non-existential".<br class=""><br class="">If I am misusing the terminology in this area, please understand<br class="">that that's what I mean when I use that word.<br class=""></blockquote><br class="">We’re not consistent about it, but an “existential value” is a value<br class="">with protocol or protocol composition type. My mnemonic for this is<br class="">that all we know is that certain operations exist (unlike a generic<br class="">value, where we also have access to the type). John could explain it<br class="">more formally. We sometimes use “existentials” as a (noun) shorthand<br class="">for “existential value”.<br class=""><br class="">In the compiler source, all protocols and protocol compositions are<br class="">referred to as “existential types”, whether they have associated<br class="">types or not. Again, a protocol asserts the existence (and<br class="">semantics) of various operations, but nothing else about the<br class="">conforming type. (Except perhaps that it’s a class.) All protocols<br class="">are thus “existential types” whether or not the language supports<br class="">values having that type.<br class=""><br class="">It is incorrect to say that protocols with associated types (or<br class="">requirements involving Self) are “non-existential”.<br class=""></blockquote><br class="">I haven't heard people using this term myself, but I imagine they<br class="">probably mean "can't form an existential value with the protocol".<br class="">There certainly appears to be a lot of confusion in the community with<br class="">many not realizing that this is a temporary limitation of the<br class="">implementation, not a necessary fact.<br class=""></blockquote><br class="">As far as I know there is no known way to make protocols with Self<br class="">requirements usefully “existentiable,” or whatever you want to<br class=""></blockquote></blockquote></blockquote>call it.<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">So unless I'm missing something, in this respect, the limitation<br class=""></blockquote></blockquote></blockquote>is not<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">temporary at all.<br class=""></blockquote><br class="">Take a look at the Equatable example in the opening existentials<br class="">section of Doug's manifesto:<br class=""><br class=""></blockquote></blockquote><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160229/011666.html" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160229/011666.html</a><br class=""><blockquote type="cite" class=""><br class="">Yes, note that I said *usefully* “existential.”<br class=""></blockquote><br class="">Fair enough. &nbsp;But note that I was only talking about the inability to<br class="">form and open such an existential which appears likely to be a<br class="">temporary limitation given the generics manifesto (of course things<br class="">could change).<br class=""><br class=""><blockquote type="cite" class=""> While we can of course downcast in this way, you have to handle the<br class="">failure case and it's not like you can use this to make a<br class="">heterogeneous Set&lt;Hashable&gt;. &nbsp;AFAICT, this is not at all like what<br class="">happens with associated types, where Collection&lt;Element: Int&gt; has<br class="">obvious uses.<br class=""></blockquote><br class="">We can’t use this to form Set&lt;Hashable&gt; because existentials don’t<br class="">conform to the protocol. &nbsp;I know there is complexity in implementing<br class="">this and it is not possible to synthesize conformance of the<br class="">existential for all protocols, but AFAIK it isn’t a settled point that<br class="">we won’t try to improve the situation in some way. &nbsp;<br class=""></blockquote><br class="">Of course. &nbsp;I'm just trying to point out that such existentials are<br class="">likely to be a whole lot less useful than many people might think.<br class=""><br class=""><blockquote type="cite" class="">Maybe we can make progress here somehow.<br class=""></blockquote><br class="">Maybe. &nbsp;It's a research project.<br class=""><br class=""><blockquote type="cite" class="">In the meantime, we can make a simple wrapper type to provide the<br class="">required conformance and make a Set&lt;HashableWrapper&gt; that allows us to<br class="">put Hashable into a Set. &nbsp;This isn’t ideal but it is a lot less<br class="">boilerplate than is involved in manual type erasure today where you<br class="">need to define a struct, base class, and wrapper class. &nbsp;I’d say<br class="">that’s a win even if we’d like to do better in the future.<br class=""><br class="">struct HashableWrapper: Hashable {<br class=""> &nbsp;&nbsp;&nbsp;var value: Hashable<br class=""> &nbsp;&nbsp;&nbsp;public var hashValue: Int { return base.hashValue }<br class="">}<br class=""><br class="">public func ==(lhs: HashableWrapper, res: HashableWrapper) -&gt; Bool {<br class=""> &nbsp;&nbsp;&nbsp;if let lhsValue = lhs.value openas T { // T is a the type of<br class="">lhsValue, a copy of the value stored in lhs<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if let rhsValue = rhs.value as? T { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// is res also a T?<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// okay: lhsValue and rhsValue are both of type T, which<br class="">we know is Equatable<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if lhsValue == rhsValue { <br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br class=""> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br class=""> &nbsp;&nbsp;&nbsp;}<br class=""> &nbsp;&nbsp;&nbsp;return false<br class="">}<br class=""><br class="">(We could also do this with a generic Wrapper&lt;T&gt; and conditional<br class="">conformance in an `extension Wrapper: Hashable where T == Hashable` if<br class="">we don’t want a bunch of wrapper types laying around)<br class=""></blockquote><br class="">I don't think I"ve made my point very well. &nbsp;Equatable (the<br class="">Self-requirement part of Hashable) has a simple answer when the types<br class="">don't match, as I noted in the POP talk. &nbsp;Let me put it differently:<br class="">existentializing a protocol with Self requirements comes with<br class="">limitations that I'm betting most people haven't recognized. &nbsp;For<br class="">example, you won't be able to add two arbitrary FloatingPoint<br class="">existentials. &nbsp;I think many people view working with existentials as<br class="">“easier” or “cleaner” than working with generics, but haven't realized<br class="">that if you step around the type relationships encoded in Self<br class="">requirements and associated types you end up with types that appear to<br class="">interoperate but in fact trap at runtime unless used in exactly the<br class="">right way.<br class=""></div></div></blockquote><div><br class=""></div><div>I was thinking more about that, and it seems that of all the possible generics extensions, the least ‘generic’ might be the most interesting in the short term: a type safe way to open existentials&nbsp;</div><div><br class=""></div><div>But rather than Doug, strawman suggestion:</div><div><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">if let storedInE1 = e1 openas T {     // T is a the type of storedInE1, a copy of the value stored in e1
  if let storedInE2 = e2 as? T {      // is e2 also a T?
    if storedInE1 == storedInE2 { … } // okay: storedInT1 and storedInE2 are both of type T, which we know is Equatable
  }
}</pre><div class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class=""><font face="Helvetica" class="">I’d rather have something like this (using the new extended ‘if/where’)</font></pre><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">if let storedInE1 = e1 as? T;
   let storedInE2 = e2 as? T;
       storedInE1 == storedInE2 { … } // okay: storedInT1 and storedInE2 are both of type T, which we know is Equatable
  }
}</pre></div><div class=""><div class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">which with my ongoing little pet-project might go down to</pre><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">if let! e1 as? T;
   let! e2 as? T;
       e1 == e2 { … } // okay: e1 and e2 are both of type T, which we know is Equatable
  }
}</pre></div></div><div class=""><br class=""></div></div><br class=""><blockquote type="cite" class=""><div class=""><div 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>