> On May 13, 2016, at 8:18 AM, Matthew Johnson <[email protected]> wrote:
> 
> 
> 
> 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. 
> 
> 'Self' is not invariant when used as a return type so I'm not sure what you 
> mean.

That's a property of a conformance. Class conformances are inherited, so they 
have to satisfy a protocol's requirements . Within the protocol definition, or 
in a protocol extension, `Self` is a generic parameter bound to a specific 
conforming type. When you conform a base class to a type, that means `Self == 
Base` and `Self == Derived` must be possible, but `Self` is never 
simultaneously `Base` and `Derived`.

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

That will likely change once resilient Swift frameworks start to exist. 
Changing `Self` to `StaticSelf` or back would also be a nonresilient change, so 
if frameworks get this wrong, they wouldn't be able to fix it without breaking 
ABI, which makes this even more problematic.

-Joe

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

Reply via email to