[swift-users] Weird protocol behaviour.

Mikhail Seriukov zloisop at gmail.com
Fri Dec 30 10:26:19 CST 2016


So as the *foo<A:P>(_ x:A) *function is generic, when we call *foo(x) *compiler
needs to determine what type is *A *to be able to create concrete function.
But x defined as *let x = X() as P *so we only know about it that it
conforms to *P *but not its real type to put instead of *A*. Right?
But where is the "Protocols do not conform to themselves" limitation is
coming out?

2016-12-30 18:25 GMT+07:00 Rien <Rien at balancingrock.nl>:

>
> > On 30 Dec 2016, at 12:14, Mikhail Seriukov via swift-users <
> swift-users at swift.org> wrote:
> >
> > Ok,
> > But I think I still do not get it.
> > What does really happen when we write this?
> >> let x = X() as P
> >>
>
> 'X()' creates a value.
> 'as P’ constrains the value such that the only things we know about it is
> that the value will conform to the protocol P
> ‘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.
>
> Rien.
>
> > As I said, I expect x to be Any<P> after that. If it is, then it should
> be ok IMO.
> > But if it is not then what is the actual type of x?
> >
> > So the real question is how the type checker works here?
> >
> >
> > 2016-12-25 22:13 GMT+07:00 Slava Pestov <spestov at apple.com>:
> >
> >> On Dec 22, 2016, at 4:43 PM, Howard Lovatt via swift-users <
> swift-users at swift.org> 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.
> >
> > 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.
> >
> > Slava
> >
> >>
> >> 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/20161230/27a5ae6c/attachment.html>


More information about the swift-users mailing list