> On May 13, 2016, at 9:06 AM, Matthew Johnson <[email protected]> wrote:
> 
> 
>> On May 13, 2016, at 10:39 AM, Joe Groff <[email protected]> wrote:
>> 
>>> 
>>> 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.
> 
> You can say this about many things.  It seems less problematic than having no 
> way to express this.  Frameworks would not be required to use it if the 
> authors have concerns about ABI.

In this particular case, making conformances non-inheritable, under the 
conformer's control, would avoid the issue of the framework having to 
anticipate its users' needs.

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

Reply via email to