[swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

Matthew Johnson matthew at anandabits.com
Fri May 13 10:28:23 CDT 2016


> On May 13, 2016, at 1:45 AM, Patrick Smith via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Could protocol Self change to just the first behaviour for classes?
> 
> If a conformance absolutely needs to have a method returning ‘only me but not my subclasses’, then it sets that conforming method to be final.

It does not say the method returns “only me but not my subclasses”.  It just says “subclasses are not *required* to return an instance of their own type, the original conforming type is sufficient to meet the requirement”.

This is quite a bit different from a ‘final’ requirement.  Subclasses are allowed to override the implementation if desired.  If they do choose to override the implementation they have more flexibility in *how* to implement it and what signature to expose.  This is exactly the same as a method in Base that is declared as returning Base rather than returning Self. 


> 
> 
>> On 13 May 2016, at 4:38 PM, Vladimir.S <svabox at gmail.com> wrote:
>> 
>> The proposed StaticSelf when used as `->StaticSelf` in protocol means ‘myself or my some *base* class’. I.e. if this requirement was implemented in one of base classes, any subclass automatically conforms to the protocol as it has `->(myself or some base class)` in his hierarchy.
>> 
>> This is the difference with `->Self` in protocol which requires 'myself'.
>> 
>> On 13.05.2016 7:21, Patrick Smith via swift-evolution wrote:
>>> I didn’t really understand some of the lead in discussion examples
>>> regarding protocols A and B each being interwoven, but I would prefer to
>>> see StaticSelf only used for concrete types, and protocols only to use
>>> Self. If Self has problems with non-final classes, then maybe how it
>>> works in protocols could change. A class could interpret a protocol’s
>>> ‘Self’ as ‘myself or my subclasses’?
>>> 
>>> Maybe instead of introducing StaticSelf it could be renamed simply Self,
>>> and ‘Self’ as used in protocols could change to something else?
>>> ‘Instance’ perhaps?
>>> 
>>>> On 13 May 2016, at 12:21 PM, 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
>>> 
>>> _______________________________________________ swift-evolution mailing
>>> list swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
> 
> _______________________________________________
> 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