<div dir="ltr">I like the way the motivation for this feature has been explained here. Now that the reasoning behind it is evident, I have to say I'm leaning towards the "InvariantSelf" name--after all, you describe this feature in the title as "an invariant self."<div class="gmail_extra"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 12, 2016 at 7:49 PM, Matthew Johnson via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Erica Sadun and I have written a proposal are following up the recent discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf, an invariant Self.<div><div><br></div><div>The recent discussion can be found here: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565</a></div><div><br></div><div>The proposal can be found here: <a href="https://github.com/anandabits/swift-evolution/blob/static-self/proposals/NNNN-static-self.md" target="_blank">https://github.com/anandabits/swift-evolution/blob/static-self/proposals/NNNN-static-self.md</a></div><div><br></div><div>We look forward to continuing the discussion. We plan to submit a PR in the near future after incorporating your final feedback.</div><div><br></div><div>Thanks,</div><div>Matthew</div><div><h1 style="font-size:37px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif">Introducing StaticSelf, an Invariant Self</h1><ul style="margin-top:21px;margin-bottom:21px;padding-left:1.5em;color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;font-size:15px"><li style="font-size:17px">Proposal: TBD</li><li style="font-size:17px">Authors: <a href="https://github.com/anandabits" style="color:rgb(13,110,161);text-decoration:none" target="_blank">Matthew Johnson</a>, <a href="https://github.com/erica" style="color:rgb(13,110,161);text-decoration:none" target="_blank">Erica Sadun</a></li><li style="font-size:17px">Status: TBD</li><li style="font-size:17px">Review manager: TBD</li></ul><h2 style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif">Introduction</h2><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">This proposal introduces a new keyword that provides consistent invariant type semantics in all contexts.</p><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em"><em style="line-height:1">The Swift-evolution thread about this topic can be found here: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565" style="color:rgb(13,110,161);text-decoration:none" target="_blank">[RFC] #Self</a></em></p><h2 style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif">Motivation</h2><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">The distinction between covariant and non-covariant type references come into play when<br>conforming non-final classes to protocols. Fixing a protocol requirement to a covarying type<br>means that a method returning <code style="line-height:1">Self</code> must be overriden by all subclasses in order to return<br>the correct, matching type.</p><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">This proposal builds on the covariant construct <code style="line-height:1">Self</code> accepted in <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md" style="color:rgb(13,110,161);text-decoration:none" target="_blank">SE–0068</a><br>to introduce an invariant type identifier. It enables protocol declarations to consistently<br>refer to a type that is fixed at compile time. This ensures that subclasses can inherit<br>protocol implementations without having to re-implement that code at each level of<br>inheritance.</p><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">Under this proposal, a new identifier keyword is fixed in use <em style="line-height:1">at the point of protocol conformance</em><br>to the static type of that construct. </p><pre style="margin-top:21px;margin-bottom:21px;color:rgb(17,17,17);font-size:15px;min-height:36px;background-color:rgb(248,248,248)"><code style="line-height:inherit;display:block;padding:0.5em;color:rgb(51,51,51);min-height:auto"><span><span style="font-weight:bold">class</span> <span style="color:rgb(68,85,136);font-weight:bold">A</span>: <span>MyProtocol</span></span></code></pre><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">The invariant <code style="line-height:1">StaticSelf</code> identifier will always refer to <code style="line-height:1">A</code>, unlike <code style="line-height:1">Self</code>, which is covarying and refers to<br>the type of the actual instance. Since multiple inheritance for non-protocol types is disallowed,<br>this establishes this invariant type identifier with no possibility for conflict.</p><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">Consider the following example, under the current system:</p><pre style="margin-top:21px;margin-bottom:21px;color:rgb(17,17,17);font-size:15px;min-height:204px;background-color:rgb(248,248,248)"><code style="line-height:inherit;display:block;padding:0.5em;color:rgb(51,51,51);min-height:auto"><span><span style="font-weight:bold">protocol</span> <span style="color:rgb(68,85,136);font-weight:bold">StringCreatable</span> </span>{
<span style="font-weight:bold">static</span> <span><span style="font-weight:bold">func</span> <span style="color:rgb(153,0,0);font-weight:bold">createWithString</span><span>(s: String)</span></span> -> <span>Self</span>
}
<span><span style="font-weight:bold">extension</span> <span style="color:rgb(68,85,136);font-weight:bold">NSURL</span>: <span style="color:rgb(68,85,136);font-weight:bold">StringCreatable</span> </span>{
<span style="color:rgb(153,153,136);font-style:italic">// cannot conform because NSURL is non-final</span>
<span style="color:rgb(153,153,136);font-style:italic">// error: method 'createWithString' in non-final class 'NSURL' must return `Self` to conform to protocol 'A'</span>
}</code></pre><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">Introducing a static, invariant version of <code style="line-height:1">Self</code> permits the desired conformance:</p><pre style="margin-top:21px;margin-bottom:21px;color:rgb(17,17,17);font-size:15px;min-height:288px;background-color:rgb(248,248,248)"><code style="line-height:inherit;display:block;padding:0.5em;color:rgb(51,51,51);min-height:auto"><span><span style="font-weight:bold">protocol</span> <span style="color:rgb(68,85,136);font-weight:bold">StringCreatable</span> </span>{
<span style="font-weight:bold">static</span> <span><span style="font-weight:bold">func</span> <span style="color:rgb(153,0,0);font-weight:bold">createWithString</span><span>(s: String)</span></span> -> <span>StaticSelf</span>
}
<span><span style="font-weight:bold">extension</span> <span style="color:rgb(68,85,136);font-weight:bold">NSURL</span>: <span style="color:rgb(68,85,136);font-weight:bold">StringCreatable</span> </span>{
<span style="color:rgb(153,153,136);font-style:italic">// can now conform conform because NSURL is fixed and matches the static</span>
<span style="color:rgb(153,153,136);font-style:italic">// type of the conforming construct. Subclasses need not re-implement</span>
<span style="color:rgb(153,153,136);font-style:italic">// <span>NOTE:</span> the return type can be declared as StaticSelf *or* as NSURL</span>
<span style="color:rgb(153,153,136);font-style:italic">// they are interchangeable</span>
<span style="font-weight:bold">static</span> <span><span style="font-weight:bold">func</span> <span style="color:rgb(153,0,0);font-weight:bold">createWithString</span><span>(s: String)</span></span> -> <span>StaticSelf</span> {
<span style="color:rgb(153,153,136);font-style:italic">// ...</span>
}
}</code></pre><h3 style="color:rgb(17,17,17);margin:21px 0px;font-size:20px;line-height:21px;font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif">Additional Utility</h3><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">The utility of <code style="line-height:1">StaticSelf</code> is not limited to protocols. A secondary use enables code to refer to the lexical context’s current type without explicitly mentioning its name. This provides a useful shortcut when referencing static type members with especially long names and when re-purposing code between types.</p><pre style="margin-top:21px;margin-bottom:21px;color:rgb(17,17,17);font-size:15px;min-height:225px;background-color:rgb(248,248,248)"><code style="line-height:inherit;display:block;padding:0.5em;color:rgb(51,51,51);min-height:auto"><span><span style="font-weight:bold">class</span> <span style="color:rgb(68,85,136);font-weight:bold">StructWithAVeryLongName</span> </span>{
<span style="font-weight:bold">static</span> <span><span style="font-weight:bold">func</span> <span style="color:rgb(153,0,0);font-weight:bold">foo</span><span>()</span></span> -> <span>String</span> {
<span style="color:rgb(153,153,136);font-style:italic">// ...</span>
}
<span><span style="font-weight:bold">func</span> <span style="color:rgb(153,0,0);font-weight:bold">bar</span><span>()</span></span> {
<span style="color:rgb(153,153,136);font-style:italic">// ...</span>
<span style="font-weight:bold">let</span> s = <span>StaticSelf</span>.foo()
<span style="color:rgb(153,153,136);font-style:italic">//</span>
}
}</code></pre><h2 style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif">Detailed Design</h2><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">This proposal introduces <code style="line-height:1">StaticSelf</code>, a new keyword that may be used in protocols to refer to the invariant static type of a conforming construct. <code style="line-height:1">StaticSelf</code> may also be used in the lexical context of any type declaration. In such use, the keyword is identical to spelling out the full name of that type.</p><h2 style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif">Impact on existing code</h2><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">Being additive, there should be no impact on existing code.</p><h2 style="color:rgb(17,17,17);font-size:27px;line-height:42px;margin-top:42px;margin-bottom:21px;font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif">Alternatives considered</h2><p style="color:rgb(17,17,17);font-family:'Helvetica Neue',Helvetica,Arial,Verdana,sans-serif;word-wrap:break-word;margin:1.3125em 0px;font-size:1.1429em;line-height:1.3125em">The keyword is not fixed at this time. Alternatives that have been discussed include <code style="line-height:1">StaticType</code>, <code style="line-height:1">InvariantSelf</code>, <code style="line-height:1">SelfType</code>, or <code style="line-height:1">Type</code>. The community is welcome to bikeshed on the most clear and concise name for this keyword.</p></div></div></div><br>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div></div>