[swift-users] Weird protocol behaviour.

Rien Rien at Balancingrock.nl
Fri Dec 30 10:38:18 CST 2016


> On 30 Dec 2016, at 17:26, Mikhail Seriukov <zloisop at gmail.com> wrote:
> 
> 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?

I believe so.

> But where is the "Protocols do not conform to themselves" limitation is coming out?

I think it was a reference to earlier in the discussion where a protocol was passed as a parameter.

Rien.

> 
> 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
> 
> 



More information about the swift-users mailing list