<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Aug 26, 2016 at 1:27 PM, Charles Srstka <span dir="ltr">&lt;<a href="mailto:cocoadev@charlessoft.com" target="_blank">cocoadev@charlessoft.com</a>&gt;</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"><span class=""><blockquote type="cite">On Aug 26, 2016, at 11:02 AM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:<br></blockquote><div><blockquote type="cite"><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Really? I wasn&#39;t aware that you could work around the `override` keyword (the one that&#39;s required for classes). How do you do that?</div></div></blockquote><br></div></span><div>By implementing the subclass’s method before the superclass’s. You can try this yourself:</div><div><br></div><div>- - - Library code: - - -</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">open</span><span> </span><span style="color:#bb2ca2">class</span><span> Superclass {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">public</span><span> </span><span style="color:#bb2ca2">init</span><span>() {}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">public</span><span> </span><span style="color:#bb2ca2">func</span><span> foo() {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)"><span style="color:#000000">        </span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span><span>&quot;foo called in library&quot;</span><span style="color:#000000">)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>}</span></div></div><div><span><br></span></div><div>- - - App code: - - -</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">import</span><span> FooLibrary</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">class</span><span> Subclass: </span><span style="color:#4f8187">Superclass</span><span> {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)"><span style="color:#000000">    </span><span style="color:#bb2ca2">func</span><span style="color:#000000"> bar() { </span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span><span>&quot;bar called in the app&quot;</span><span style="color:#000000">) }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>}</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">let</span><span> obj = </span><span style="color:#4f8187">Subclass</span><span>()</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)"><span>obj</span><span style="color:#000000">.</span><span style="color:#31595d">foo</span><span style="color:#000000">()</span></div></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)"><span style="color:#000000"><br></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)"><span style="color:#000000"><span style="font-family:Helvetica;font-size:12px">- - - output: - - -</span></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)"><span style="color:#000000"><span style="font-family:Helvetica;font-size:12px"><br></span></span></div><div style="margin:0px;line-height:normal"><span><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><b>foo called in library</b></span></div><div style="margin:0px;line-height:normal"><span><b>Program ended with exit code: 0</b></span></div></div><span class=""><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><b><br></b></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:12px">- - - - - -</span></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:12px"><br></span></span></div></span><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:12px">Now: Change the library code to:</span></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:12px"><br></span></span></div><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:#bb2ca2">open</span><span> </span><span style="color:#bb2ca2">class</span><span> Superclass {</span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span>    </span><span style="color:#bb2ca2">public</span><span> </span><span style="color:#bb2ca2">init</span><span>() {}</span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span>    </span><span style="color:#bb2ca2">public</span><span> </span><span style="color:#bb2ca2">func</span><span> foo() {</span></div><div style="color:rgb(209,47,27);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:#000000">        </span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span><span>&quot;foo called in library&quot;</span><span style="color:#000000">)</span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span>        </span><span style="color:#31595d">bar</span><span>()</span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span>    }</span></div><p style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal;min-height:13px"><span>    </span><br></p><div style="color:rgb(0,132,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:#000000">    </span><span>// Hey look, I didn&#39;t even use that stupid new &#39;open&#39; keyword.</span></div><div style="color:rgb(209,47,27);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:#000000">    </span><span style="color:#bb2ca2">public</span><span style="color:#000000"> </span><span style="color:#bb2ca2">func</span><span style="color:#000000"> bar() { </span><span style="color:#3d1d81">print</span><span style="color:#000000">(</span><span>&quot;bar called in library&quot;</span><span style="color:#000000">) }</span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span>}</span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><br></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:12px">- - - Run the app again without compiling it, and: - - -</span></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal"><span><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><b>foo called in library</b></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><b>bar called in the app</b></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><b>Program ended with exit code: 0</b></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><b><br></b></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:12px">- - -</span></span></div><div style="color:rgb(0,0,0);font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span><span style="font-family:Helvetica;font-size:12px"><br></span></span></div><div style="margin:0px;line-height:normal"><span>Voilà: I overrode a method (a supposedly non-overridable one, at that) with no “override” keyword.</span></div></span></div></div></span></div></span></div></div></blockquote><div><br></div><div>This is clearly a bug in the implementation, not part of the design. Expect it to be fixed as the code for `open` matures. It&#39;s certainly not a precedent to be emulated for designing another feature.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span>Just as File A in your earlier example can implement a protocol method without realizing it, Subclass here has unintentionally overridden a superclass method. This is because ‘override’ does not, to the best of my knowledge, mean anything to the actual machine code that is produced; rather, it signals the developer’s *intent,* thus allowing the compiler to assist in making sure the developer does the right thing.</span></div><div style="margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal"><span>I’d actually argue that the example above is a much, much bigger problem than the objection you raised, as it can actually produce unintended behavior at runtime, whereas the example with protocols can’t.</span></div><div style="margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal"><span>As for the protocol example, I’d like to refine Option 3 from last night slightly:</span></div><div style="margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal">Option 4: A keyword is required on a method declaration if and only if the containing type is declared as conforming to its protocol, either in its definition or in an extension that is visible within the current scope.</div></span></div></div></span></div></span></div></div></blockquote><div><br></div><div>Extensions are not first-class entities and have no visibility of their own. In any case, you have not solved the problem, which has nothing to do with whether something is &quot;reasonable to know&quot;: when a default implementation A is overridden by implementation B, implementation A may be visible only in a *more restricted* access scope than implementation B. (This is not the case with overriding superclass members in subclasses.) It can be perfectly &quot;reasonable to know&quot; about both A and B, but there is still no way you can indicate this knowledge by appending a keyword to the declaration for implementation B if the access scope for implementation A is unutterable where B is declared.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal">This allows the extension to remain empty in your example, but puts the responsibility on the developer to declare conforming methods when it is reasonable to know that they will satisfy a protocol.</div><span class="HOEnZb"><font color="#888888"><div style="margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal"><span>Charles</span></div><div style="margin:0px;line-height:normal"><span><br></span></div></font></span></span></div></div></span></div></span></div></div></blockquote></div><br></div></div>