<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><blockquote type="cite" class=""><div class="">Am 26.05.2016 um 22:07 schrieb Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class=""><br class=""><br class="">Sent from my iPad</div><div class=""><br class="">On May 26, 2016, at 2:49 PM, Austin Zheng via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">I alway enjoy hearing your ideas.<div class=""><br class=""></div><div class="">This is quite interesting. It's basically a way to define an ad-hoc interface that a type doesn't need to explicitly declare it conforms to. I know Golang works similarly; if a Go type implements all the requirements of an interface it conforms automatically.</div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">There are positives and negatives to allowing this sort of ad-hoc interface. </div></div></div></blockquote><div class=""><br class=""></div><div class="">Agree. It would definitely make the language "feel" a bit more fluid. But it doesn't add any expressive power and could have undesirable consequences.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">This would make for a good standalone proposal -- both because it's complex enough to deserve its own discussion, and because if the community is interested someone would have to work through all the implications in order to put together a proposal. It would be quite a big change.</div></div></div></blockquote><div class=""><br class=""></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">I don't see how this is different from a protocol other than the lack of requirement to declare conformance explicitly. The need to explicitly declare conformance is a design decision that I believe the core team feels pretty strongly about. </span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">That said, it hasn't been debated by the community yet so if someone feels strongly about dropping explicit conformance declarations it might be worth pitching the idea, if for not other reason than to have a discussion about it on the lost.</span></div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">Best,</div><div class="">Austin</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Thu, May 26, 2016 at 11:56 AM, Adrian Zubarev via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<br class=""><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=""><p class="">I’d like to throw one idea of mine in the room I couldn’t stop thinking when I read one of Thorsten’s replies on SE–0095 review thread.</p><p class="">This <a href="https://en.wikipedia.org/wiki/Type_system#Existential_types" target="_blank" class="">wiki section</a> explains the existential types where we have something like this:</p>
<blockquote class=""><p class="">"T = ∃X { a: X; f: (X → int); }
This could be implemented in different ways; for example:</p>
<ul class="">
<li class="">intT = { a: int; f: (int → int); }</li>
<li class="">floatT = { a: float; f: (float → int); }</li>
</ul>
</blockquote><p class="">We discussed how we could create existential types with constraints for protocols and classes so far. Such an existential can’t create something like in the example above.</p><div class=""><br class=""></div></div></div></blockquote></div></div></div></blockquote></div></div></blockquote><br class="">With Joe’s information about unbound associated types still being usable, e.g. as `a.Element` with the current proposal we should actually already have existential types like defined in Wikipedia or Haskell (except for the name "existential“ being used differently in Swift, e.g. for protocols without associated types, too).</div><div><br class=""></div><div>protocol T {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>associatedtype X</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>var a: X { get }</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>func f(_ value: X) -> Int</div><div>}</div><div><br class=""></div><div>// use T as existential in Wikipedia’s sense</div><div>func foo(t: any<T>) -> Int {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>return t.f(t.a) // t.X is not bound to a fixed type but as it is used consistently it works for any T</div><div>}</div><div><br class=""></div><div><br class=""></div><div>struct A : T {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>var a: Int</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>func f(_ value: Int) -> Int { return value }</div><div>}</div><div><br class=""></div><div><div>struct B : T {</div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>var a: String</div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>func f(_ value: String) -> Int { return value.characters.count }</div><div>}</div><div><br class=""></div><div>let a = A(a: 42)</div><div>let b = B(a: "hello")</div><div>let x = foo(a) // 42</div><div>let y = foo(b) // 5</div><div><br class=""></div><div class=""><br class=""></div><div class="">Actually in this case we could have written foo() also as generic function (without having to bind X!)</div><div class=""><br class=""></div><div class="">func foo<P: T>(t: P) -> Int {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>return t.f(t.a)</div><div class="">}</div><div class=""><br class=""></div><div class="">This works already today.</div><div class=""><br class=""></div><div class=""><br class=""></div></div><div>-Thorsten</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><blockquote type="cite" class=""><div class=""><div class="gmail_extra"><div class="gmail_quote"><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=""><p class="">I’m not sure if we need this at all, I’d say it’s a <u class=""><em class="">nice to have</em></u> idea of mine.</p><p class="">To solve this we could introduce a new scope similar to protocols today but without the need to explicitly conform types to this existential.</p>
<pre class=""><code class="">// the above example can become
existential T {
associatedtype X
var a: X
func f(_ value: X) -> Int
}
struct A /* no explicit conformance to T needed */ {
var a: Int
init(a: Int) { self.a = a }
func f(_ value: Int) -> Int { return value }
}
let store: T = A() // this could or should work, just because we do have visibility to all constraints from T in A here
</code></pre></div></div></blockquote></div></div></div></blockquote></div></div></blockquote><div><br class=""></div><div>Isn’t this just structural subtyping as opposed to nominal subtyping (which I strongly prefer)?<div class=""><br class=""></div><div class="">-Thorsten</div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""></blockquote></div></div></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><blockquote type="cite" class=""><div class=""><div class="gmail_extra"><div class="gmail_quote"><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=""><pre class=""><code class="">
// if we had `private var a: Int` in A we wouldn't be able to store A inside `store`
</code></pre><p class="">I din’t though if <code class="">existential</code> could have potential to replace <code class="">Any<…></code> completely. Until now I just wanted to solve that particular issue so please don’t judge with me. :)</p><p class="">Just because of associated types we won’t be able to use <code class="">store</code> in this example, but there might be more trivial examples where one would use such existential type (for only visible portion at compile or dynamically at run-time) without explicit conformance.</p>
<pre class=""><code class="">struct B {
var x: Int = 42
var y: Double = -100.5
}
struct C: SomeProtocol {
var y: Double = 0.0
var x: Int = 10
}
existential SomeShinyThing {
var x: Int
var y: Double
}
// we should be safe here because the compiler has visibility for
// internal B and C here
let anotherStore: SomeShinyThing = B() /* or */ C()
// otherwise one could use dynamic casts
if let thirdStore = instanceOfCShadowedAsSomeProtocol as? SomeShinyThing { … }
</code></pre><p class="">Feel to tear this idea apart as you want. :D</p><span class="HOEnZb"><font color="#888888" class=""><div class=""><br class="webkit-block-placeholder"></div></font></span></div><span class="HOEnZb"><font color="#888888" class=""><div class=""><div style="font-family: Helvetica, Arial; font-size: 13px; margin: 0px;" class=""><br class=""></div> <br class=""> <div class=""><div style="font-family:helvetica,arial;font-size:13px" class="">-- <br class="">Adrian Zubarev<br class="">Sent with Airmail</div></div></div><div class=""><div class=""><br class="webkit-block-placeholder"></div></div></font></span></div><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="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div>
</div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></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>