> 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
