<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><span></span></div><div><div><br><br>Sent from my iPad</div><div><br>On May 12, 2016, at 9:21 PM, Joe Groff <<a href="mailto:jgroff@apple.com">jgroff@apple.com</a>> wrote:<br><br></div><blockquote type="cite"><div><span></span><br><blockquote type="cite"><span>On May 12, 2016, at 5:49 PM, Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>The invariant StaticSelf identifier will always refer to A, unlike Self, which is covarying and refers to</span><br></blockquote><blockquote type="cite"><span>the type of the actual instance. Since multiple inheritance for non-protocol types is disallowed,</span><br></blockquote><blockquote type="cite"><span>this establishes this invariant type identifier with no possibility for conflict.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Consider the following example, under the current system:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>protocol StringCreatable </span><br></blockquote><blockquote type="cite"><span>{</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>static func createWithString(s: String) -> Self</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>extension NSURL: StringCreatable </span><br></blockquote><blockquote type="cite"><span>{</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>// cannot conform because NSURL is non-final</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>// error: method 'createWithString' in non-final class 'NSURL' must return `Self` to conform to protocol 'A'</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Introducing a static, invariant version of Self permits the desired conformance:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>protocol StringCreatable </span><br></blockquote><blockquote type="cite"><span>{</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>static func createWithString(s: String) -> StaticSelf</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>extension NSURL: StringCreatable </span><br></blockquote><blockquote type="cite"><span>{</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>// can now conform conform because NSURL is fixed and matches the static</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>// type of the conforming construct. Subclasses need not re-implement</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>// NOTE: the return type can be declared as StaticSelf *or* as NSURL</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>// they are interchangeable</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>static func createWithString(s: String) -> StaticSelf</span><br></blockquote><blockquote type="cite"><span> { </span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>// ...</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span> }</span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><span></span><br><span>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. </span></div></blockquote><div><br></div><div><span style="background-color: rgba(255, 255, 255, 0);">'Self' is not invariant when used as a return type so I'm not sure what you mean.</span></div><br><blockquote type="cite"><div><span>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. </span></div></blockquote><div><br></div><div>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.</div><br><blockquote type="cite"><div><span>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.</span><br></div></blockquote><div><br></div><div>This proposal does not allow protocols to legislate whether conformance is inherited or not. It just allows the protocol to specify more precisely <b><i>how</i></b> requirements are inherited. </div><div><br></div><div>When I write a class Base with non-final methods that return instances of Base I can choose whether to state the return type as Self (covariant) or Base (invariant, under this proposal StaticSelf would also be an alternative way to state this). If I choose to specify Base as the return type derived classes *may* override the method but are not required to. Further, if they *do* override the method they are allowed to choose whether their implementation returns Base or Derived.</div><div><br></div><div>I believe protocols should have the same flexibility. If superclasses can control the variance of the return types of their inherited methods why shouldn't protocols be able to do so as well? The weaker requirement can be very useful in some cases.</div><div><br></div><div>I think the case for StaticSelf is:</div><div><br></div><div>1. It is useful as a general substitute for the name of the containing type.</div><div>2. It solves real world use cases of providing protocol conformance.</div><div>3. It is a small change (on the surface, I can't speak to implementation) and may have a chance at making it into Swift 3.</div><div>4. The previous discussion about controlling conformance at the usage site didn't really seem to reach any conclusions. My impression is that this is a feature that is difficult to design well and probably isn't going to be a priority, at least for a while.</div><div>5. StaticSelf is perfectly compatible with such a feature if it is introduced in the future. </div><div><br><blockquote type="cite"><div><span></span><br><span>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.</span><br></div></blockquote><div><br></div><div>That's a fair criticism for that use case. Chris also mentioned that. 'Type' is the best shorter option we came up with. We didn't go that route in the proposal because feels like it could be more confusing for those first learning it. That said, we are willing to go with whatever the community decides on. </div><div><br></div><div>If you like one of the alternatives better or have any new ideas please let us know...</div><br><blockquote type="cite"><div><span></span><br><span>-Joe</span></div></blockquote></div></div></body></html>