Sent from my iPad

> On May 12, 2016, at 9:21 PM, Joe Groff <[email protected]> wrote:
> 
> 
>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution 
>> <[email protected]> wrote:
>> 
>> The invariant StaticSelf identifier will always refer to A, unlike Self, 
>> which is covarying and refers to
>> the type of the actual instance. Since multiple inheritance for non-protocol 
>> types is disallowed,
>> this establishes this invariant type identifier with no possibility for 
>> conflict.
>> 
>> Consider the following example, under the current system:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> Self
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // cannot conform because NSURL is non-final
>> 
>> 
>> // error: method 'createWithString' in non-final class 'NSURL' must return 
>> `Self` to conform to protocol 'A'
>> 
>> }
>> 
>> Introducing a static, invariant version of Self permits the desired 
>> conformance:
>> 
>> protocol StringCreatable 
>> {
>> 
>> static func createWithString(s: String) -> StaticSelf
>> 
>> }
>> 
>> 
>> extension NSURL: StringCreatable 
>> {
>> 
>> // can now conform conform because NSURL is fixed and matches the static
>> 
>> 
>> // type of the conforming construct. Subclasses need not re-implement
>> 
>> 
>> // NOTE: the return type can be declared as StaticSelf *or* as NSURL
>> 
>> 
>> //       they are interchangeable
>> 
>> 
>> static func createWithString(s: String) -> StaticSelf
>> { 
>> 
>> // ...
>> 
>> }
>> }
> 
> As I've noted before, I don't think this makes sense to encode in the 
> protocol. `Self` is already effectively invariant within a protocol.
> 
> As I've noted before, I don't think this makes sense to encode in the 
> protocol. `Self` is already effectively invariant within a protocol.

'Self' is not invariant when used as a return type so I'm not sure what you 
mean.

> If a protocol doesn't have the foresight to use StaticSelf, then you still 
> have the same problems retroactively conforming class hierarchies to the 
> protocol.

True, but in many use cases we are in control of the protocol.  This has always 
been the case when I have personally encountered this problem.

> Whether a conformance is inherited or not feels more natural as a property of 
> a conformance, not something that can be legislated a priori by a protocol 
> definition.

This proposal does not allow protocols to legislate whether conformance is 
inherited or not.  It just allows the protocol to specify more precisely how 
requirements are inherited.   

When I write a class Base with non-final methods that return instances of Base 
I can choose whether to state the return type as Self (covariant) or Base 
(invariant, under this proposal StaticSelf would also be an alternative way to 
state this).  If I choose to specify Base as the return type derived classes 
*may* override the method but are not required to.  Further, if they *do* 
override the method they are allowed to choose whether their implementation 
returns Base or Derived.

I believe protocols should have the same flexibility.  If superclasses can 
control the variance of the return types of their inherited methods why 
shouldn't protocols be able to do so as well?  The weaker requirement can be 
very useful in some cases.

I think the case for StaticSelf is:

1. It is useful as a general substitute for the name of the containing type.
2. It solves real world use cases of providing protocol conformance.
3. It is a small change (on the surface, I can't speak to implementation) and 
may have a chance at making it into Swift 3.
4. The previous discussion about controlling conformance at the usage site 
didn't really seem to reach any conclusions.  My impression is that this is a 
feature that is difficult to design well and probably isn't going to be a 
priority, at least for a while.
5. StaticSelf is perfectly compatible with such a feature if it is introduced 
in the future.  

> 
> Something like StaticSelf might still be useful as shorthand within a class 
> definition with a long-winded name, though `StaticSelf` feels kind of long as 
> a shortcut to me.

That's a fair criticism for that use case.  Chris also mentioned that.  'Type' 
is the best shorter option we came up with.  We didn't go that route in the 
proposal because feels like it could be more confusing for those first learning 
it.  That said, we are willing to go with whatever the community decides on.  

If you like one of the alternatives better or have any new ideas please let us 
know...

> 
> -Joe
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to