[swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self
Matthew Johnson
matthew at anandabits.com
Fri May 13 10:24:50 CDT 2016
> On May 13, 2016, at 1:26 AM, David Hart <david at hartbit.com> wrote:
>
> Totally agree. It feels weird to have protocols decide on how "Self" conformance a are inherited. It should a decision for the conforming type.
Do you have any suggestions on how we allow the conforming type to make that decision? Last time we had that discussion it didn’t produce clear answer. It turns out there is quite a bit of complexity involved in doing this.
>
>> On 13 May 2016, at 04:21, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
>>
>>
>>> On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org> 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. 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. 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.
>>
>> 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.
>>
>> -Joe
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
More information about the swift-evolution
mailing list