<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 20, 2016, at 8:20 PM, Howard Lovatt &lt;<a href="mailto:howard.lovatt@gmail.com" class="">howard.lovatt@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Adding protected access and abstract methods and classes might be easier, since then you could do:<div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class="">/* abstract */<span style="" class=""> </span><span style="color:rgb(187,44,162)" class="">class</span><span style="" class=""> Base {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="color:rgb(0,132,0)" class="">/* protected abstract */</span> <span style="color:rgb(187,44,162)" class="">func</span> methodToBeOverridden() -&gt; <span style="color:rgb(112,61,170)" class="">String</span> { <span style="color:rgb(61,29,129)" class="">fatalError</span>(<span style="color:rgb(209,47,27)" class="">"Abstract"</span>) }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="color:rgb(187,44,162)" class="">final</span> <span style="color:rgb(187,44,162)" class="">func</span> controlsWhenOverrideIsCalled() -&gt; <span style="color:rgb(112,61,170)" class="">String</span>{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:rgb(187,44,162)" class="">var</span><span style="" class=""> s = </span>"In 'super' before override call.\n"</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(49, 89, 93);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; s += </span>methodToBeOverridden<span style="" class="">()</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:rgb(187,44,162)" class="">return</span><span style="" class=""> s + </span>".\nIn 'super' after override call."</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color:rgb(187,44,162)" class="">class</span> Derived: <span style="color:rgb(79,129,135)" class="">Base</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="color:rgb(0,132,0)" class="">/* protected */</span> <span style="color:rgb(187,44,162)" class="">override</span> <span style="color:rgb(187,44,162)" class="">func</span> methodToBeOverridden() -&gt; <span style="color:rgb(112,61,170)" class="">String</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color:rgb(187,44,162)" class="">return</span><span style="" class=""> </span>"In override"</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color:rgb(187,44,162)" class="">let</span> d = <span style="color:rgb(79,129,135)" class="">Derived</span>()</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(49, 89, 93);" class=""><span style="color:rgb(79,129,135)" class="">d</span><span style="" class="">.</span>controlsWhenOverrideIsCalled<span style="" class="">()</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><font face="arial, helvetica, sans-serif" class="">Which results in:</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="color:rgb(209,47,27)" class="">In 'super' before override call.</span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="color:rgb(209,47,27)" class="">In override.</span><span style="color:rgb(209,47,27)" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="color:rgb(209,47,27)" class="">In 'super' after override call.</span><span style="color:rgb(209,47,27)" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="color:rgb(209,47,27)" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><font face="arial, helvetica, sans-serif" class="">Calls to super could then be eliminated from the language!</font></div></div></div></div></blockquote><div><br class=""></div><div>Not really. &nbsp;This covers some use cases but by no means all of them. &nbsp;It also adds complexity to the design (by introducing two names). &nbsp;</div><div><br class=""></div><div>Aside from that, we are not going to see `protected` access control in Swift. &nbsp;It does not fit the access control model of the language, which is scope-based rather than type-based. &nbsp;This is a good thing IMO.</div><div><br class=""></div><div>-Matthew</div><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On 21 January 2016 at 11:53, Jesse Squires <span dir="ltr" class="">&lt;<a href="mailto:jesse.d.squires@gmail.com" target="_blank" class="">jesse.d.squires@gmail.com</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks Matthew and Howard! A lot of good points there.<br class="">
<br class="">
There are certainly a few more possible semantics for overrides than I was initially thinking. It’s not clear to me if the language should support each use case or not. Doing so seems to add unnecessary complexity for (potentially) little gain.<br class="">
<br class="">
I can’t say for sure, but my guess is that the *most common* scenario is: "if a method is overridden, it must call super first". This would also make automatically synthesizing the call to super simpler, which I think is a great idea. Clients then have less of a burden when subclassing.<br class="">
However, as noted, non-void returns complicate this. Also, I agree that re-purposing `required` could be confusing. I’m open to ideas for an alternative keyword.<br class="">
<br class="">
Again, a lot of good ideas/feedback. I’m actually not sure where this leaves us. :) Accounting for all of the possible semantics seems too complex and burdensome, though I think our current state is insufficient. And perhaps accounting for only the simplest scenario, "if a method is overridden, it must call super first", would only further highlight the lack of ability to express the other possible semantics.<br class="">
<br class="">
¯\_(ツ)_/¯&nbsp; I’d love to hear if anyone else has ideas or shares these concerns!<br class="">
<br class="">
Jesse<br class="">
<br class="">
<br class="">
&gt; On Jan 18, 2016, at 11:34 AM, Howard Lovatt via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;<br class="">
&gt;&gt;&gt;<br class="">
&gt;&gt;&gt; Are there other languages worth investigating which have the requires super first/last semantics you note?<br class="">
&gt;&gt;<br class="">
&gt;&gt; I don’t know of any languages that support this.&nbsp; It is not the most common semantic, but when it occurs it seems important enough that it would be better if it could be specified in the language itself and enforced rather than left to documentation.<br class="">
&gt;<br class="">
&gt; BETA has this ability, but it worked rather differently than modern OO languages (which work more like its predecessor Simula). In BETA you can only ever call the top most method, it can then optionally call the immediately overriding method. The syntax BETA uses is `inner(&lt;args&gt;)`. Probably easier with examples (in BETArised Swift):<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; class Base {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; func finalM() { print("finalM") }<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; func mustOverrideM() {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("beforeInner")<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inner()<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("afterInner")<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; }<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; class Derived: Base {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; func mustOverrideM() {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("inInner")<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; }<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt; Methods `finalM` and `Derived.mustOverrideM` are automatically final because they do not call inner.<br class="">
&gt;<br class="">
&gt; You can't make an instance of `Base` because method `Base.mustOverrideM` needs to be overridden, i.e. `Base` is automatically abstract.<br class="">
&gt;<br class="">
&gt; If you:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; let d = Derived()<br class="">
&gt;&nbsp; &nbsp; d.mustBeOverriddenM()<br class="">
&gt;<br class="">
&gt; Then it prints:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; beforeInner<br class="">
&gt;&nbsp; &nbsp; inInner<br class="">
&gt;&nbsp; &nbsp; afterInner<br class="">
&gt;<br class="">
&gt; _______________________________________________<br class="">
&gt; swift-evolution mailing list<br class="">
&gt; <a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
<br class="">
</blockquote></div><br class=""><br clear="all" class=""><div class=""><br class=""></div>-- <br class=""><div class="gmail_signature">&nbsp; -- Howard.<br class=""></div>
</div>
</div></blockquote></div><br class=""></body></html>