<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="">Ah, thanks, I forgot! <div class="">I still consider this a bug, though (will have to read up again what the reasons are for that behavior).<div class=""><br class=""></div><div class="">-Thorsten</div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">Am 08.06.2016 um 21:43 schrieb Austin Zheng <<a href="mailto:austinzheng@gmail.com" class="">austinzheng@gmail.com</a>>:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">It's not possible, even with Swift's current implementation of existentials. A protocol type P isn't considered to conform to itself, thus the following is rejected:<div class=""><br class=""></div><div class=""><div class="">let a : MyProtocol = // ...</div><div class="">func myFunc<T : MyProtocol>(x: T) {</div><div class=""> // ....</div><div class="">}</div><div class="">myFunc(a) // "Cannot invoke 'myFunc' with an argument list of type MyProtocol"</div></div><div class=""><br class=""></div><div class="">Changing how this works is probably worth a proposal by itself.</div><div class=""><br class=""></div><div class="">Austin</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Jun 8, 2016 at 12:34 PM, Thorsten Seitz 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 class="HOEnZb"><div class="h5"><br class="">
> Am 08.06.2016 um 20:33 schrieb Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>:<br class="">
><br class="">
><br class="">
> on Tue Jun 07 2016, Matthew Johnson <<a href="http://matthew-at-anandabits.com" class="">matthew-AT-anandabits.com</a>> wrote:<br class="">
><br class="">
>>> On Jun 7, 2016, at 9:15 PM, Dave Abrahams <<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>> wrote:<br class="">
>>><br class="">
>>><br class="">
>>> on Tue Jun 07 2016, Matthew Johnson <<a href="http://matthew-at-anandabits.com" class="">matthew-AT-anandabits.com</a> <<a href="http://matthew-at-anandabits.com/" rel="noreferrer" target="_blank" class="">http://matthew-at-anandabits.com/</a>>> wrote:<br class="">
>>><br class="">
>><br class="">
>>>>> On Jun 7, 2016, at 4:13 PM, Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class="">
>>>>><br class="">
>>>>><br class="">
>>>>> on Tue Jun 07 2016, Matthew Johnson <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class="">
>>>>><br class="">
>>>><br class="">
>>>>>>> , 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="">
>>>>>><br class="">
>>>>>> Trap at runtime? How so? Generalized existentials should still be<br class="">
>>>>>> type-safe.<br class="">
>>>>><br class="">
>>>>> There are two choices when you erase static type relationships:<br class="">
>>>>><br class="">
>>>>> 1. Acheive type-safety by trapping at runtime<br class="">
>>>>><br class="">
>>>>> FloatingPoint(3.0 as Float) + FloatingPoint(3.0 as Double) // trap<br class="">
>>>>><br class="">
>>>>> 2. Don't expose protocol requirements that involve these relationships,<br class="">
>>>>> which would prevent the code above from compiling and prevent<br class="">
>>>>> FloatingPoint from conforming to itself.<br class="">
>>>>><br class="">
>>>>>> Or are you talking about the hypothetical types / behaviors people<br class="">
>>>>>> think they want when they don’t fully understand what is happening...<br class="">
>>>>><br class="">
>>>>> I don't know what you mean here. I think generalized existentials will<br class="">
>>>>> be nice to have, but I think most people will want them to do something<br class="">
>>>>> they can't possibly do.<br class="">
>>>><br class="">
>>>> Exactly. What I meant is that people think they want that expression<br class="">
>>>> to compile because they don’t understand that the only thing it can do<br class="">
>>>> is trap. I said “hypothetical” because producing a compile time error<br class="">
>>>> rather than a runtime trap is the only sane thing to do. Your comment<br class="">
>>>> surprised me because I can’t imagine we would move forward in Swift<br class="">
>>>> with the approach of trapping.<br class="">
>>><br class="">
>>> I would very much like to be able to create instances of “Collection<br class="">
>>> where Element == Int” so we can throw away the wrappers in the stdlib.<br class="">
>>> That will require some type mismatches to be caught at runtime via<br class="">
>>> trapping.<br class="">
>><br class="">
>> For invalid index because the existential accepts a type erased index?<br class="">
><br class="">
> Exactly.<br class="">
><br class="">
>> How do you decide where to draw the line here? It feels like a very<br class="">
>> slippery slope for a language where safety is a stated priority to<br class="">
>> start adopting a strategy of runtime trapping for something as<br class="">
>> fundamental as how you expose members on an existential.<br class="">
><br class="">
> If you don't do this, the alternative is that “Collection where Element<br class="">
> == Int” does not conform to Collection. That's weird and not very<br class="">
> useful. You could expose all the methods that were on protocol<br class="">
> extensions of Collection on this existential, unless they used<br class="">
> associated types other than the element type. But you couldn't pass the<br class="">
> existential to a generic function like<br class="">
><br class="">
> func scrambled<C: Collection>(_ c: C) -> [C.Element]<br class="">
<br class="">
</div></div>I don’t understand. Why couldn’t an existential be passed to that function?<br class="">
<br class="">
-Thorsten<br class="">
<div class="HOEnZb"><div class="h5"><br class="">
<br class="">
<br class="">
><br class="">
>> IMO you should *have* to introduce unsafe behavior like that manually.<br class="">
><br class="">
> Collection where Element == Int & Index == *<br class="">
><br class="">
> ?<br class="">
><br class="">
>> Collection indices are already something that isn’t fully statically<br class="">
>> safe so I understand why you might want to allow this.<br class="">
><br class="">
> By the same measure, so are Ints :-)<br class="">
><br class="">
> The fact that a type's methods have preconditions does *not* make it<br class="">
> “statically unsafe.”<br class="">
><br class="">
>> But I don’t think having the language's existentials do this<br class="">
>> automatically is the right approach. Maybe there is another approach<br class="">
>> that could be used in targeted use cases where the less safe behavior<br class="">
>> makes sense and is carefully designed.<br class="">
><br class="">
> Whether it makes sense or not really depends on the use-cases. There's<br class="">
> little point in generalizing existentials if the result isn't very useful.<br class="">
> The way to find out is to take a look at the examples we currently have<br class="">
> of protocols with associated types or Self requirements and consider<br class="">
> what you'd be able to do with their existentials if type relationships<br class="">
> couldn't be erased.<br class="">
><br class="">
> We have known use-cases, currently emulated in the standard library, for<br class="">
> existentials with erased type relationships. *If* these represent the<br class="">
> predominant use cases for something like generalized existentials, it<br class="">
> seems to me that the language feature should support that. Note: I have<br class="">
> not seen anyone build an emulation of the other kind of generalized<br class="">
> existential. My theory: there's a good reason for that :-).<br 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="">
> <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="">
_______________________________________________<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="">
</div></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></div></body></html>