[swift-evolution] [RFC] #Self

Matthew Johnson matthew at anandabits.com
Wed May 11 09:42:04 CDT 2016



Sent from my iPad

> On May 11, 2016, at 9:33 AM, Vladimir.S <svabox at gmail.com> wrote:
> 
>> On 11.05.2016 16:42, Matthew Johnson wrote:
>> With #Self (or Type as we're now calling it) they would not need to
>> override those requirements because the ancestor that initially declared
>> conformance provides an inherited implementation that remains valid for
>> all of its descendants.
> 
> OK.. I see your point, thank you. But probably we thinks differently about the #Self 'behavior' and how it should be treated in case of protocol conformance.
> 
> First of all, the initial proposal (which I base all my understanding on):
> On 10.05.2016 16:15, Erica Sadun via swift-evolution wrote:
> >----------------------------------<
> To focus SE-0068 and narrow its scope, I removed the `#Self` part of the proposal. This offered compile-time substitution of the defining type for a related #Self literal:
> 
>    A further static identifier, #Self expands to static type of the code it appears within, completing the ways code may want to refer to the type it is declared in.
> 
>        #Self expands to the static type of the code it is declared within. In value types, this is always the same as Self. In reference types, it refers to the declaring type. #Self will offer a literal textual replacement just like #file, etc.
> >----------------------------------<
> 
> So, again, we have protocol
> 
> protocol A {
>  func f()->#Self
> }
> 
> What does it mean for me? : Each class C, conformed to protocol A, should have func f() that returns exactly this class.
> 
> so, let's have
> 
> class B: A {
>  func f()->B {} // conforms to protocol
> // or could be written as(the same):
> //func f()->#Self {} // conforms to protocol
> }
> 
> class C: A {
>  func f()->C {} // conforms to protocol
> }
> 
> class D: A {
>  func f()->D {} // conforms to protocol
> }
> 
> and now, you want to conform some existed non-final class to A protocol:
> 
> class E {
>  func f()->E {} // just has such method
> }
> 
> extension E: A {} // seems like OK at this step
> 
> after this, what's the state of some existed derived from E classes ?
> 
> class F: E {}
> class G: F {}
> 
> You conformed the base class E to A protocol. This automatically *reuqire* that F & G also conforms to A protocol. They *must* be `is A`.
> But I insist, they does not conform to A protocol as I understand the #Self proposal.
> 
> F().f() *must*(because of protocol A) return instance of F, but F only has f()->C from base class
> 
> G().f() *must*(because of protocol A) return instance of G, but G only has f()->C from base class

I think you meant E here, not C.

> 
> This is why I don't understand how #Self could help to achieve the target with NSURL conformance.
> These are my points. Please point if I'm wrong somewhere.

You are describing the behavior of Self, not #Self.  

>        #Self expands to the static type of the code it is declared within. In value types, this is always the same as Self. In reference types, it refers to the declaring type.

For implementations of protocol requirements the declaring type is the type that declares conformance.

Self is covariant, #Self (or Type) is invariant.  That is the difference.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160511/9ae33835/attachment.html>


More information about the swift-evolution mailing list