<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 Apr 27, 2016, at 12:31 PM, Erica Sadun <<a href="mailto:erica@ericasadun.com" class="">erica@ericasadun.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Apr 27, 2016, at 12:25 PM, Douglas Gregor <<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>> wrote:<br class=""><div class=""><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Apr 27, 2016, at 10:10 AM, Erica Sadun <<a href="mailto:erica@ericasadun.com" class="">erica@ericasadun.com</a>> wrote:<br class=""><div class=""><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">From the Swift Programming Language: <i class="">Methods on a subclass that override the superclass’s implementation are marked with override—overriding a method by accident, without override, is detected by the compiler as an error. The compiler also detects methods with override that don’t actually override any method in the superclass.</i></div><div class=""><br class=""></div><div class="">I would like to extend this cautious approach to protocols, forcing the developer to deliberately override an implementation that’s inherited from a protocol extension. This would prevent accidental overrides and force the user to proactively choose to implement a version of a protocol member that already exists in the protocol extension.</div><div class=""><br class=""></div><div class="">I envision this as using the same `override` keyword that’s used in class based inheritance but extend it to protocol inheritance:</div><div class=""><br class=""></div><div class="">protocol A {</div><div class=""> func foo()</div><div class="">}</div><div class=""><br class=""></div><div class="">extension A {</div><div class=""> func foo() { .. default implementation … }</div><div class="">}</div><div class=""><br class=""></div><div class="">type B: A {</div><div class=""><br class=""></div><div class=""> override required func foo () { … overrides implementation … }</div><div class="">}</div></div></div></blockquote><div class=""><br class=""></div><div class="">A couple questions about your pitch:</div><div class=""><br class=""></div><div class="">1) What is “required” doing there? </div></div></div></div></blockquote><div class=""><br class=""></div>I threw it in not because I’m tied to it but because I wanted it to be part of the conversation.</div><div class="">This is a requirement from conforming to the protocol.</div></div></div></blockquote><div><br class=""></div><div>Ah. Note that this isn’t *quite* the meaning of “required” for initializers of classes (where it means “my subclasses must override this”), but in practice it’s basically the only reason why anyone uses “required” for initializers.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">2) Is “override” only required when there is a default implementation of the protocol requirement, or is it required whenever you are implementing a protocol requirement?</div></div></div></blockquote><div class=""><br class=""></div><div class="">Override is only because it is overriding the default implementation of the protocol requirement. Without that default implementation there would be no override, it would simply be satisfying the requirement.</div></div></div></div></blockquote><div><br class=""></div><div>For me, this doesn’t provide additional value of “required”: i.e., the value of having a keyword here is in telling me that I failed to implement a requirement when I’ve clearly said that I wanted to implement a requirement. Whether there was a default there or not isn’t really very interesting. Plus, a default could be added later to a requirement that I implement: that change has zero impact on how my code works (before or after), but now I’d be require to add an “override” keyword when I recompile.</div><div><br class=""></div><div>Contrast that with classes: if you recompile against a new version of a library and the compiler tells you that you need to add “override”, it’s serious because the semantics of your program will change if you’re now overriding something that you weren’t before.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>* If the former, it might be the case that it’s too easy to forget to add the “override” keyword (because it’s needed for some implementations of protocol requirements but not others), which undercuts the value of having it.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Forcing the override keyword makes it clear at the definition point that the story extends beyond the method or whatever to point to a default implementation that is being replaced. I *really* like having that reference in terms of both code construction (“I am doing this as a deliberate act”) with the compiler complaining otherwise, and in terms of code self documentation (“I know this was added deliberately, what default did it override?”)</div></div></div></div></blockquote><div><br class=""></div><div>I see the former (“I am doing this as a deliberate act”) as a very common complaint; the latter not nearly as much. What motivates that? And does it justify adding a *second* keyword to these declarations?</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I’d also like to bring up two related topics, although they probably should at some point move to their own thread if they have any legs:<br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Related topic 1: How should a consumer handle a situation where two unrelated protocols both require the same member and offer different default implementations. Can they specify which implementation to accept or somehow run both? </div><div class=""><br class=""></div><div class="">type B: A, C {</div><div class=""> override required func foo() { A.foo(); C.foo() }</div><div class="">}</div></div></div></blockquote><div class=""><br class=""></div><div class="">I think the right answer here is for the compiler to produce an ambiguity if you don’t implement the requirement yourself, and then solving your “related topic 2” lets you choose which implementation you want.</div></div></div></blockquote><div class=""><br class=""></div><div class="">How do you choose which one? What syntax? For example:</div><div class=""><br class=""></div><div class="">required func foo = A.foo</div><div class=""><br class=""></div><div class="">would be the simplest approach</div></div></div></div></blockquote><div><br class=""></div>type B: A, C {</div><div> override required func foo() { A.foo(self)() }</div><div>}</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Related topic 2: How can a consumer “inherit” the behavior of the default implementation (like calling super.foo() in classes) and then extend that behavior further. This is a bit similar to how the initialization chaining works. I’d like to be able to call A.foo() and then add custom follow-on behavior rather than entirely replacing the behavior.</div><div class=""><br class=""></div><div class="">type B: A {</div><div class=""> override required func foo() { A.foo(); … my custom behavior … }</div><div class="">}</div></div></div></blockquote><div class=""><br class=""></div><div class="">Seems totally reasonable to me. One ugly syntax: A.foo(self)(), leveraging the currying of self?</div></div></div></blockquote><div class=""><br class=""></div><div class="">Ugly but it would pretty much do it for me. It offers an expressive way to say “Please execute the A.foo behavior using the self instance”. Does 3 still support this?</div></div></div></div></blockquote></div><br class=""><div class="">Probably not? I actually don’t know ;)</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div class=""><br class=""></div></body></html>