<div dir="ltr">So as the <span style="font-size:12.8px"><b>foo<A:P>(_ x:A) </b>function is generic, when we call <b>foo(x) </b>compiler needs to determine what type is <b>A </b>to be able to create concrete function. But x defined as <b>let x = X() as P </b>so we only know about it that it conforms to <b>P </b>but not its real type to put instead of <b>A</b>. Right?<br>But where is the "</span><span style="font-size:12.8px">Protocols do not conform to themselves</span><span style="font-size:12.8px">" limitation is coming out?</span></div><div class="gmail_extra"><br><div class="gmail_quote">2016-12-30 18:25 GMT+07:00 Rien <span dir="ltr"><<a href="mailto:Rien@balancingrock.nl" target="_blank">Rien@balancingrock.nl</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> On 30 Dec 2016, at 12:14, Mikhail Seriukov via swift-users <<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>> wrote:<br>
><br>
> Ok,<br>
> But I think I still do not get it.<br>
> What does really happen when we write this?<br>
>> let x = X() as P<br>
>><br>
<br>
</span>'X()' creates a value.<br>
'as P’ constrains the value such that the only things we know about it is that the value will conform to the protocol P<br>
‘let x =‘ assigns the value to a constant, and the only thing we know about that constant is that we can call an operation of protocol P on it.<br>
<span class="HOEnZb"><font color="#888888"><br>
Rien.<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> As I said, I expect x to be Any<P> after that. If it is, then it should be ok IMO.<br>
> But if it is not then what is the actual type of x?<br>
><br>
> So the real question is how the type checker works here?<br>
><br>
><br>
> 2016-12-25 22:13 GMT+07:00 Slava Pestov <<a href="mailto:spestov@apple.com">spestov@apple.com</a>>:<br>
><br>
>> On Dec 22, 2016, at 4:43 PM, Howard Lovatt via swift-users <<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>> wrote:<br>
>><br>
>> The following variation works:<br>
>><br>
>> protocol P {}<br>
>><br>
>> class P1:P {}<br>
>><br>
>> class X:P1 {}<br>
>><br>
>> func foo<A:P>(_ x:A) {}<br>
>><br>
>> func bar() {<br>
>> //let x = X() // this compiles<br>
>> let x = X() as P1 // this does not compile. Why?<br>
>> foo(x)<br>
>> }<br>
>><br>
>> Which adds credence to the bug theory.<br>
><br>
> It’s an intentional limitation. Protocols do not conform to themselves. Lifting the restriction would be difficult to do efficiently given our representation of generics and protocols at runtime.<br>
><br>
> Slava<br>
><br>
>><br>
>> Note two changes: 1. two levels of inheritance and 2. change to classes. If you do two levels using protocols it doesn't work if you use either classes or structs.<br>
>><br>
>><br>
>> -- Howard.<br>
>><br>
>> On 23 December 2016 at 07:29, Kevin Nattinger <<a href="mailto:swift@nattinger.net">swift@nattinger.net</a>> wrote:<br>
>> I recall seeing a request on the -evolution list for something like `T := X` to indicate it could be X itself or anything inheriting / implementing it, so it’s certainly known behavior, if not desired. IMO it’s a bug and `:` should be fixed to include the root type, whether or not that requires a discussion on -evolution.<br>
>><br>
>>> On Dec 22, 2016, at 2:17 PM, Howard Lovatt via swift-users <<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>> wrote:<br>
>>><br>
>>> I suspect a compiler bug since A is a P. The equivalent in Java works:<br>
>>><br>
>>> interface P {}<br>
>>> class X implements P {}<br>
>>><br>
>>> <A extends P> void foo(A x) {}<br>
>>><br>
>>> void bar() {<br>
>>> final P x = new X();<br>
>>> foo(x);<br>
>>> }<br>
>>><br>
>>> -- Howard.<br>
>>><br>
>>> On 23 Dec 2016, at 3:19 am, Rien via swift-users <<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>> wrote:<br>
>>><br>
>>>> IMO the error message says it all:<br>
>>>><br>
>>>> Playground execution failed: error: MyPlayground8.playground:9:5: error: cannot invoke 'foo' with an argument list of type '(P)'<br>
>>>> foo(x)<br>
>>>> ^<br>
>>>><br>
>>>> MyPlayground8.playground:9:5: note: expected an argument list of type '(A)'<br>
>>>> foo(x)<br>
>>>> ^<br>
>>>><br>
>>>> I.e. you are passing in a protocol while the function is specified for a type.<br>
>>>> Said other way: On which data do you expect the protocol to operate?<br>
>>>><br>
>>>> Regards,<br>
>>>> Rien<br>
>>>><br>
>>>> Site: <a href="http://balancingrock.nl" rel="noreferrer" target="_blank">http://balancingrock.nl</a><br>
>>>> Blog: <a href="http://swiftrien.blogspot.com" rel="noreferrer" target="_blank">http://swiftrien.blogspot.com</a><br>
>>>> Github: <a href="http://github.com/Swiftrien" rel="noreferrer" target="_blank">http://github.com/Swiftrien</a><br>
>>>> Project: <a href="http://swiftfire.nl" rel="noreferrer" target="_blank">http://swiftfire.nl</a><br>
>>>><br>
>>>><br>
>>>><br>
>>>><br>
>>>>> On 22 Dec 2016, at 17:05, Mikhail Seriukov via swift-users <<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>> wrote:<br>
>>>>><br>
>>>>> Hello community! I' wondering if somebody can explain this to me.<br>
>>>>> Please take look at the snippet.<br>
>>>>><br>
>>>>> protocol P {}<br>
>>>>> struct X:P {}<br>
>>>>><br>
>>>>> func foo<A:P>(_ x:A) {}<br>
>>>>><br>
>>>>> func bar() {<br>
>>>>> //let x = X() // this compiles<br>
>>>>> let x = X() as P // this does not compile. Why?<br>
>>>>> foo(x)<br>
>>>>> }<br>
>>>>><br>
>>>>> I expect the both cases to work though. But only first works? And I do not understand why.<br>
>>>>> My coworkers said that it is a compiler bug, but I'm not shure it is.<br>
>>>>> Thanks for the help.<br>
>>>>> ______________________________<wbr>_________________<br>
>>>>> swift-users mailing list<br>
>>>>> <a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
>>>>> <a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br>
>>>><br>
>>>> ______________________________<wbr>_________________<br>
>>>> swift-users mailing list<br>
>>>> <a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
>>>> <a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br>
>>> ______________________________<wbr>_________________<br>
>>> swift-users mailing list<br>
>>> <a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
>>> <a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br>
>><br>
>><br>
>> ______________________________<wbr>_________________<br>
>> swift-users mailing list<br>
>> <a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
>> <a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> swift-users mailing list<br>
> <a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
> <a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br>
<br>
</div></div></blockquote></div><br></div>