<div dir="ltr">Chris, as I wrote above, this idea has been discussed previously on several occasions, and the principal reason why it has been abandoned each time is that it cannot accommodate retroactive modeling. I&#39;ll refer you again to three previous threads discussing this and closely related matters:<div><br></div><div><div style="font-size:12.8px"><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005380.html" target="_blank">https://lists.swift.org/<wbr>pipermail/swift-evolution/<wbr>Week-of-Mon-20160104/005380.<wbr>html</a> <br></div><div style="font-size:12.8px"><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160229/011792.html" target="_blank">https://lists.swift.org/<wbr>pipermail/swift-evolution/<wbr>Week-of-Mon-20160229/011792.<wbr>html</a><br></div><div style="font-size:12.8px"><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160425/015920.html" target="_blank">https://lists.swift.org/<wbr>pipermail/swift-evolution/<wbr>Week-of-Mon-20160425/015920.<wbr>html</a></div></div><div><br></div><div>If, after familiarizing yourself with the previous discussions, you feel like there is an aspect of the topic that has not yet been considered, then of course feel free to start another discussion.</div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 25, 2016 at 5:36 PM, Christopher Kornher via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</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"><br><div><span class=""><blockquote type="cite"><div>On Aug 25, 2016, at 4:32 PM, Christopher Kornher &lt;<a href="mailto:ckornher@me.com" target="_blank">ckornher@me.com</a>&gt; wrote:</div><br><div><div style="word-wrap:break-word"><div><div style="margin:0px;line-height:normal"><span>I hope that my brief email wasn’t the final word on this :(</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>Does anyone think that a proposal to require “override” for overrides of protocol extension methods and variables (?) would be worth exploring?</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>This would address a number of the issues raised in this thread, but not all.</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>My intention is not to derail this thread, and I believe that the original topic of this thread, explicit protocol conformance, is worth exploring. I respond here because of these topics are strongly related. I will start a new thread, if there is interest.</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>It is possible that tooling could address the remaining issues with overrides. JetBrains products, for example, provide navigable icons to overridden methods. There is no reason that Xcode and other tools could not automatically insert indicators like:</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>```</span></div><div style="margin:0px;line-height:normal"><span>class MyClass: MyProtocol {</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span><span style="white-space:pre-wrap">        </span>&lt; conforms &gt;</span></div><div style="margin:0px;line-height:normal"><span><span style="white-space:pre-wrap">        </span>func myMethod() -&gt; String {</span></div><div style="margin:0px;line-height:normal"><span>        <span style="white-space:pre-wrap">        </span>return “...&quot;</span></div><div style="margin:0px;line-height:normal"><span>   <span style="white-space:pre-wrap">        </span>}</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>class MyClass2: MyProtocol1, MyProtocol2 {</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span><span style="white-space:pre-wrap">        </span>&lt; conforms MyProtocol2 &gt;</span></div><div style="margin:0px;line-height:normal"><span><span style="white-space:pre-wrap">        </span>func myMethod() -&gt; String {</span></div><div style="margin:0px;line-height:normal"><span>        <span style="white-space:pre-wrap">        </span>return “...&quot;</span></div><div style="margin:0px;line-height:normal"><span>    <span style="white-space:pre-wrap">        </span>}</span></div><div style="margin:0px;line-height:normal"><span>```</span></div><div style="margin:0px;line-height:normal"><span>Of course, there is no reason that tooling can’t replace “override” completely:</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>```</span></div><div style="margin:0px;line-height:normal"><span>class MyClass: MyOtherClass, MyProtocol1, MyProtocol2 {</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span><span style="white-space:pre-wrap">        </span>&lt; conforms MyProtocol2 &gt;</span></div><div style="margin:0px;line-height:normal"><span><span style="white-space:pre-wrap">        </span>&lt; overrides TheParentClassOfMyOtherClass&gt;</span></div><div style="margin:0px;line-height:normal"><span><span style="white-space:pre-wrap">        </span>func myMethod() -&gt; String {</span></div><div style="margin:0px;line-height:normal"><span>        <span style="white-space:pre-wrap">        </span>return “...&quot;</span></div><div style="margin:0px;line-height:normal"><span>    <span style="white-space:pre-wrap">        </span>}</span></div><div style="margin:0px;line-height:normal"><span>```</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>Replace &quot;&lt;…&gt;” with the navigable graphic of your choice and assume that user preferences would exist to show/hide these indicators.</span></div></div><div><span><br></span></div><br></div></div></blockquote><div><br></div></span><div>My cut and paste error left out this part:</div><div><br></div><div><div style="margin:0px;line-height:normal"><span>The roles of language and tooling in making code understandable is largely a matter of opinion. I personally like the current use of “override” since overriding is a common cause of serious programming errors and a mechanism for protecting against them should be built into the language and now, extended to overrides of protocol extensions.</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>It is interesting that adding “override” to structs and enums would help to open the door to true inheritance (not polymorphism) for structs and possibly even enums, if anyone knows of a use for that. This is a feature that I could have used on a few projects, but there are far more important features in the queue, and that discussion should probably wait until after Swift 4, if it happens at all.</span></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal;min-height:14px"><span></span><br></div><div style="margin:0px;line-height:normal"><span>- Chris K</span></div><div><span><br></span></div></div><div><div class="h5"><div><br></div><br><blockquote type="cite"><div><div style="word-wrap:break-word"><div><blockquote type="cite"><div>On Aug 24, 2016, at 11:13 AM, Christopher Kornher via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br><div><div dir="auto"><div>Requiring &quot;override&quot; when anything overrides a method defined in a protocol extension should be added - structure and enumerated included, of course.</div><div><br></div><div>Protocol extensions added inheritance to structs and enums and this should be made explicit.</div><div><br>Sent from my iPad</div><div><br>On Aug 24, 2016, at 12:55 AM, Charles Srstka via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><blockquote type="cite">On Aug 24, 2016, at 1:20 AM, Robert Widmann &lt;<a href="mailto:devteam.codafi@gmail.com" target="_blank">devteam.codafi@gmail.com</a>&gt; wrote:<br></blockquote><div><blockquote type="cite">2016/08/23 20:52、Charles Srstka &lt;<a href="mailto:cocoadev@charlessoft.com" target="_blank">cocoadev@charlessoft.com</a>&gt; のメッセージ:<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"><div><div><div><div><br></div><blockquote type="cite"><div><blockquote type="cite">On Aug 23, 2016, at 10:34 PM, Robert Widmann &lt;<a href="mailto:devteam.codafi@gmail.com" target="_blank">devteam.codafi@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">2016/08/23 15:29、Charles Srstka &lt;<a href="mailto:cocoadev@charlessoft.com" target="_blank">cocoadev@charlessoft.com</a>&gt; のメッセージ:<br><br></div><blockquote type="cite" 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"><div><blockquote type="cite">On Aug 23, 2016, at 2:33 PM, Robert Widmann via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</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">2016/08/22 14:30、David Cordero via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; のメッセージ:<br><br></div><blockquote type="cite" 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"><div><div dir="ltr"><br><div><b>The problem:</b></div><div>At the moment, looking at the code of a class or a struct implementing a protocol, it is hard to know what methods are actually implementing the protocol and what other methods are just part of the code of the class or struct.<br></div><div><br></div></div></div></blockquote><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"><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">That seems like a feature, not a bug.  Why should I as an author care whether a method contributes to a protocol conformance or not if the compiler can tell me that kind of information itself?</div></div></blockquote><div><br></div><div>Being able to reason about your code, what it does, and what it’s for is undesirable?</div></div></div></blockquote><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"><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">That&#39;s not an answer to the question I asked.  Why is this significant enough to warrant an entire keyword?  The clutter of a whole keyword that does nothing but wait for a developer to make a source-compatible binary-breaking change to an interface does not seem worth it.  Maybe you can convince me otherwise. </div></div></blockquote><div><br></div><div>Same reason overriding a class method warrants a keyword. It expresses the purpose more clearly, and allows the compiler to catch mistakes for us.</div><br></div></div></blockquote><div><br></div><div>That&#39;s just it: The class of mistakes one can make by not being explicit about overrides is significantly more dangerous than the class of mistakes caused by dead code leftover from trimming protocols.</div></div></div></div></div></div></blockquote><div><br></div><div>I am in the middle of a large refactor of code that was originally Objective-C and then Swift written like Objective-C, to more idiomatic protocol-oriented Swift. I am finding that in Swift’s POP idiom, protocols with overrides are serving very nearly the same purpose that overrides were serving in the old design; hence, I don’t really think either is more or less dangerous than the other.</div><br><blockquote type="cite"><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"><div><div><div><blockquote type="cite"><div><div><blockquote type="cite"><div><blockquote type="cite" 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"><div><div><blockquote type="cite"><blockquote type="cite" 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"><div><div dir="ltr"><div>```</div></div></div></blockquote><blockquote type="cite" 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"><div><div dir="ltr"><div>protocol MyProtocol {</div><div>    func myMethod() -&gt; String</div><div>}</div><div><br></div><div>class MyClass: MyProtocol {</div><div><br></div><div>   <span> </span><b>conform</b> func myMethod() -&gt; String {</div><div>        return &quot;Yuhuuu,I am conforming<span> </span><a>\\o//</a>&quot;</div><div>    }</div><div><br></div><div>    func whatever() {</div><div>        print(&quot;I am a boring method and I don&#39;t conform anything&quot;)</div><div>    }</div><div>}</div><div>```</div><div><br></div><div>It would be something similar to the current keyword `override` but for protocols. </div><div><br></div><div>Apart from improving code readability, It would allow the detection, in compilation time, of errors due to code evolution. For example redundant methods that no longer conform anything once the requirement is removed from the protocol for whatever reason.</div></div></div></blockquote><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"><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">If you make a breaking change to a protocol like this, you should have gone through a deprecation cycle to indicate to your clients the appropriate changes you&#39;re going to make to the protocol.  This aspect of the change seems to if not encourage, highlight, bad behavior.</div></blockquote></div><br><div>What if it’s your own code and all the callers are internal? What if you’re still developing the protocol and haven’t released the API interface yet?</div></div></blockquote><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"><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">Then your concerns are local enough that you know where<span> </span><i>all</i> implementations of the protocol lie and whether they require deletion or not.  The point about deprecation cycles still stands in all the cases you mention.  Just because the interface is private doesn&#39;t mean you can&#39;t take responsibility for keeping it as clean as you can.</div><br 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"><blockquote type="cite" 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"><div><div><br></div><div>Charles</div><div><br></div></div></blockquote><br 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"><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">tl;dr It seems like all of this can be subsumed by us warning about dead code.</div></div></blockquote></div><br><div>Did you look at my examples earlier in the thread? Neither of those would be caught by warning about dead code.</div></div></blockquote><div><br></div><div>The example involving the default implementation is most compelling, but it indicates that your proposed solution should focus on the protocol extension and not the implementing declaration.  Perhaps reusing one of our existing keywords can help here</div><div><br></div><div><div><span style="background-color:rgba(255,255,255,0)">protocol P {</span></div><div><span style="background-color:rgba(255,255,255,0)">  func foo() {}</span></div><div><span style="background-color:rgba(255,255,255,0)">}</span></div><div><span style="background-color:rgba(255,255,255,0)"><br></span></div><div><span style="background-color:rgba(255,255,255,0)">extension P {</span></div><div><span style="background-color:rgba(255,255,255,0)">  default func foo() {}</span></div><div><span style="background-color:rgba(255,255,255,0)">}</span></div><div><br></div><div><span style="background-color:rgba(255,255,255,0)">struct S: P {}</span></div></div><div><br></div><div>Of course, this change would be potentially source-breaking either way - I don&#39;t like the sound of an &quot;optional keyword”.  </div></div></div></div></div></div></blockquote><div><br></div><div>I can come up with a similar example without the mistake being in the extension, though:</div><div><br></div><div>protocol P {</div><div><span style="white-space:pre-wrap">        </span>func foo() {}</div><div>}</div><div><br></div><div>extension P {</div><div><span style="white-space:pre-wrap">        </span>func foo() { print(“Default Behavior”) }</div><div>}</div><div><br></div><div>struct S: P {</div><div><span style="white-space:pre-wrap">        </span>func foo() { print(“Specific Behavior”) }</div><div>}</div><div><br></div><div>So far, so good. But now I realize that the original protocol needs an argument:</div><div><br></div><div><div>protocol P {</div><div><span style="white-space:pre-wrap">        </span>func foo(bar: String) {}</div><div>}</div><div><br></div><div>extension P {</div><div><span style="white-space:pre-wrap">        </span>func foo(bar: String) { print(“Default Behavior; bar is \(bar)”) }</div><div>}</div><div><br></div><div>struct S: P {</div><div><span style="white-space:pre-wrap">        </span>func foo() { print(“Specific Behavior”) } // Whoops, forgot to update this method, and now it won’t get called<span style="font-size:11px">—</span>and we of course won’t see the carnage until runtime.</div><div>}</div></div><br><blockquote type="cite"><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"><div><div><div><div>Either way, we can all agree we need better diagnostics around these cases.</div></div></div></div></div></div></blockquote><br></div><div>No doubt.</div><div><br></div>Charles<div><br></div></div></blockquote><blockquote type="cite"><div><span>______________________________<wbr>_________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a></span><br></div></blockquote></div>______________________________<wbr>_________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br></div></blockquote></div><br></div></div></blockquote></div></div></div><br></div><br>______________________________<wbr>_________________<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/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div></div>