<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 &lt;<a href="mailto:jgroff@apple.com">jgroff@apple.com</a>&gt; 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 &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; 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) -&gt; 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) -&gt; 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>// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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) -&gt; 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. &nbsp;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. &nbsp;It just allows the protocol to specify more precisely&nbsp;<b><i>how</i></b> requirements are inherited. &nbsp;&nbsp;</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). &nbsp;If I choose to specify Base as the return type derived classes *may* override the method but are not required to. &nbsp;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. &nbsp;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? &nbsp;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. &nbsp;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. &nbsp;</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. &nbsp;Chris also mentioned that. &nbsp;'Type' is the best shorter option we came up with. &nbsp;We didn't go that route in the proposal because feels like it could be more confusing for those first learning it. &nbsp;That said, we are willing to go with whatever the community decides on. &nbsp;</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>