<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><blockquote type="cite"><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);"><b class=""><font class="">Existentials</font></b><br></span></font></div><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></font></div><div class=""><i class="" style="background-color: rgba(255, 255, 255, 0);"><font color="#000000">Opening existentials</font></i></div><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></font></div><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);">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:</span></font></div><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></font></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);">protocol Equatable {</font></div><div class=""><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);"> func ==(lhs: Self, rhs: Self) -> Bool</font></div><div class=""><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);"> func !=(lhs: Self, rhs: Self) -> Bool</font></div><div class=""><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);">}</font></div><div class=""><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);">let e1: Equatable = …</font></div><div class=""><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);">let e2: Equatable = …</font></div><div class=""><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);">if e1 == e2 { … } <i class="">// <b class="">error</b>:</i> e1 and e2 don’t necessarily have the same dynamic type</font></div></blockquote><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></font></div><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);">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:</span></font></div><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></font></div><div class=""><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);"><span class="Apple-tab-span" style="white-space: pre;">        </span> </span></font></div><div class=""><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);">if let storedInE1 = e1 openas T { // T is a the type of storedInE1, a copy of the value stored in e1</font></blockquote><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);"> if let storedInE2 = e2 as? T { // is e2 also a T?</font></blockquote><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);"> if storedInE1 == storedInE2 { … } // okay: storedInT1 and storedInE2 are both of type T, which we know is Equatable</font></blockquote><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);"> }</font></blockquote><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><font class="" color="#000000" style="background-color: rgba(255, 255, 255, 0);">}</font></blockquote></div></blockquote><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Isn't "open existential" code for "casting ∃ to ∀"? Dispatch on the underlying type is brittle and anti-modular. I should know, I tried to recover GADTs under the old system! I shudder to think of what further horrors I could concoct with this pattern formalized in the language.</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">~ Robert Widmann</span></div></div></div></body></html>