[swift-users] Weird protocol behaviour.

Zhao Xin owenzx at gmail.com
Fri Dec 23 10:34:20 CST 2016


My previous theory was wrong.

> P is an existential for x: P = … where it is upgraded to the static P in foo<A
: P>

Why it needs to be upgraded? Why not just use `P` as a protocol instead of
a `type`? Xcode error message calls `P` as a type.


Zhaoxin

On Fri, Dec 23, 2016 at 9:03 PM, Adrian Zubarev <
adrian.zubarev at devandartist.com> wrote:

> I’m not sure what you mean. P is an existential for x: P = … where it is
> upgraded to the static P in foo<A : P>, but the static P does not conform
> to the existential P, which results in an error described by the OP.
>
> x: P = … here it’s Any<P> any type that conforms to P. Any<P> is a type
> of it’s own, and when existentials will be implemented I’d assume that
> there won’t be any upgrade to P from generic context.
>
> let x: Any<P> = …
>
> foo(x)
> // A == Any<P> which should make foo equivalent to
> // `func foo(_ x: Any<P>)` or the current `func foo(_ x: P)`
>
> Right now we just cannot be explicit about existentials.
>
> Please correct me if I’m wrong. ;)
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 23. Dezember 2016 um 13:47:18, Zhao Xin (owenzx at gmail.com) schrieb:
>
> You mis-labelled you problem in your original email.
>
>     let x = X() as P // this does not compile. Why?
>     foo(x)
>
> The issue is not in line ` let x = X() as P`. It is in line ` foo(x)`,
> `x's type is P`, but `foo(:)` request a parameter type of `A`, not `P`.
>
> `func foo<A:P>(_ x:A) {}` means, `x` must be `A`, and `A` conforms `P`.
> But not all `P`s are `A`.
>
> Zhaoxin
>
> On Fri, Dec 23, 2016 at 5:26 PM, Adrian Zubarev via swift-users <
> swift-users at swift.org> wrote:
>
>> Whoops, wait a second. Correcting my self here. Copied the wrong url.
>>
>> Here is the proposal I meant. LINK
>> <https://github.com/apple/swift-evolution/blob/cd9d8b3f1923d16f4381c23d3d335d88d83e32cd/proposals/0126-refactor-metatypes.md>
>>
>>
>> --
>> Adrian Zubarev
>> Sent with Airmail
>>
>> Am 23. Dezember 2016 um 09:57:49, Adrian Zubarev (
>> adrian.zubarev at devandartist.com) schrieb:
>>
>>
>>    -
>>
>>    What are you trying to solve here?
>>    -
>>
>>    Do you heavily rely on what A can be?
>>    -
>>
>>    Can’t you just write func foo(_ x: P) {} (here P is an *existential*
>>    like [in some future] Any<P>)?!
>>    -
>>
>>    AnyObject is for classes, but you’d get the same result changing X to
>>    a class ;)
>>
>> If you want scratch the surface of what happens to protocols in a generic
>> context, you could read our proposal about meta types here
>> <https://github.com/apple/swift-evolution/blob/91725ee83fa34c81942a634dcdfa9d2441fbd853/proposals/0126-refactor-metatypes-repurpose-t-dot-self-and-mirror.md>
>> .
>>
>>
>> --
>> Adrian Zubarev
>> Sent with Airmail
>>
>> Am 23. Dezember 2016 um 09:43:34, Mikhail Seriukov via swift-users (
>> swift-users at swift.org) schrieb:
>>
>> No it does not.
>>> You have made a type out of the parameter. It’s no longer a protocol.
>>> IMO the failure here is to understand the difference between a type and
>>> a protocol.
>>> A type (even if empty) is always a combination of storage with functions
>>> (that are assumed to work on the data in storage)
>>> A protocol is just a definition of functions without the accompanying
>>> data.
>>>
>>
>> I see your point.
>> But actually when I write it as  `let x = X() as P` I really mean that I
>> want `x` to be `AnyObject` but conforming to P, not just protocol itself.
>> Is it even possible to downcast it this way?
>>
>> 2016-12-23 14:51 GMT+07:00 Marinus van der Lugt <rien at starbase55.com>:
>>
>>>
>>> On 22 Dec 2016, at 22:43, Howard Lovatt <howard.lovatt at gmail.com> wrote:
>>>
>>> The following variation works:
>>>
>>> protocol P {}
>>>
>>> class P1:P {}
>>>
>>> class X:P1 {}
>>>
>>> func foo<A:P>(_ x:A) {}
>>>
>>> func bar() {
>>>     //let x = X() // this compiles
>>>     let x = X() as P1 // this does not compile. Why?
>>>     foo(x)
>>> }
>>>
>>> Which adds credence to the bug theory.
>>>
>>>
>>>
>>> No it does not.
>>> You have made a type out of the parameter. It’s no longer a protocol.
>>> IMO the failure here is to understand the difference between a type and
>>> a protocol.
>>> A type (even if empty) is always a combination of storage with functions
>>> (that are assumed to work on the data in storage)
>>> A protocol is just a definition of functions without the accompanying
>>> data.
>>>
>>> Rien.
>>>
>>>
>>>
>>>
>>> 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.
>>>
>>>
>>>   -- Howard.
>>>
>>> On 23 December 2016 at 07:29, Kevin Nattinger <swift at nattinger.net>
>>> wrote:
>>>
>>>> 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.
>>>>
>>>> On Dec 22, 2016, at 2:17 PM, Howard Lovatt via swift-users <
>>>> swift-users at swift.org> wrote:
>>>>
>>>> I suspect a compiler bug since A is a P. The equivalent in Java works:
>>>>
>>>> interface P {}
>>>> class X implements P {}
>>>>
>>>> <A extends P> void foo(A x) {}
>>>>
>>>> void bar() {
>>>>     final P x = new X();
>>>>     foo(x);
>>>> }
>>>>
>>>> -- Howard.
>>>>
>>>> On 23 Dec 2016, at 3:19 am, Rien via swift-users <swift-users at swift.org>
>>>> wrote:
>>>>
>>>> IMO the error message says it all:
>>>>
>>>> Playground execution failed: error: MyPlayground8.playground:9:5:
>>>> error: cannot invoke 'foo' with an argument list of type '(P)'
>>>>    foo(x)
>>>>    ^
>>>>
>>>> MyPlayground8.playground:9:5: note: expected an argument list of type
>>>> '(A)'
>>>>    foo(x)
>>>>    ^
>>>>
>>>> I.e. you are passing in a protocol while the function is specified for
>>>> a type.
>>>> Said other way: On which data do you expect the protocol to operate?
>>>>
>>>> Regards,
>>>> Rien
>>>>
>>>> Site: http://balancingrock.nl
>>>> Blog: http://swiftrien.blogspot.com
>>>> Github: http://github.com/Swiftrien
>>>> Project: http://swiftfire.nl
>>>>
>>>>
>>>>
>>>>
>>>> On 22 Dec 2016, at 17:05, Mikhail Seriukov via swift-users <
>>>> swift-users at swift.org> wrote:
>>>>
>>>>
>>>> Hello community! I' wondering if somebody can explain this to me.
>>>>
>>>> Please take look at the snippet.
>>>>
>>>>
>>>> protocol P {}
>>>>
>>>> struct X:P {}
>>>>
>>>>
>>>> func foo<A:P>(_ x:A) {}
>>>>
>>>>
>>>> func bar() {
>>>>
>>>>    //let x = X() // this compiles
>>>>
>>>>    let x = X() as P // this does not compile. Why?
>>>>
>>>>    foo(x)
>>>>
>>>> }
>>>>
>>>>
>>>> I expect the both cases to work though. But only first works? And I do
>>>> not understand why.
>>>>
>>>> My coworkers said that it is a compiler bug, but I'm not shure it is.
>>>>
>>>> Thanks for the help.
>>>>
>>>> _______________________________________________
>>>>
>>>> swift-users mailing list
>>>>
>>>> swift-users at swift.org
>>>>
>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>
>>>>
>>>> _______________________________________________
>>>> swift-users mailing list
>>>> swift-users at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>
>>>> _______________________________________________
>>>> swift-users mailing list
>>>> swift-users at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>
>>>>
>>>>
>>>
>>>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
>>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20161224/7fa96863/attachment.html>


More information about the swift-users mailing list