<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 16 Nov 2016, at 22:37, Sean Heber via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">That could be kind of neat - perhaps a syntax more like this so that there isn’t another bare keyword:<br class=""><br class="">override(after) func viewDidLoad() {<br class="">}<br class=""><br class="">and:<br class=""><br class="">override(before) func viewDidLoad() {<br class="">}<br class=""><br class="">Which would allow you to specify where your code happens - either before or after the superclass method, essentially. Leaving out before/after would still behave as expected and you’d have to call super yourself (or not):<br class=""><br class="">override func viewDidLoad() {<br class=""> &nbsp;// stuff<br class=""> &nbsp;super.viewDidLoad()<br class=""> &nbsp;// more stuff<br class="">}<br class=""><br class=""><br class="">A potentially neat thing about this is that you could possibly then impose restrictions on subclasses like so:<br class=""><br class="">final(before) func viewDidLoad() {}<br class=""><br class="">Which could mean that the “before” slot is “final” - therefore you cannot do either of these:<br class=""><br class="">override func viewDidLoad() {}<br class="">override(before) func viewDidLoad() {}</div></div></blockquote><br class=""></div><div>I like the basic idea, and I especially like the clarification via override at the call site, but I wanted to add the design that I preferred from the last discussion.</div><div><br class=""></div><div>Basically the idea was that the parent method would have a @super() attribute with of the following attributes available to use within it:</div><div><br class=""></div><div><ul class="MailOutline"><li class=""><b class="">before</b>: super must be called before all other statements in an overriding method's body.</li><li class=""><b class="">required</b>: the super call is required. If neither before or after is specified it may be placed anywhere in the method's body, but must occur in all paths. This is the default if a method has a @super attribute.</li><li class=""><b class="">optional</b>: the super call is not required.</li><li class=""><b class="">after</b>: super must be called after all other statements in an overriding method's body.</li><li class=""><b class="">error</b>: failing to call the super method either at all or in the correct location is an error. This is the default.</li><li class=""><b class="">warning</b>: failing to call the super method either at all or in the correct location is a warning that a developer may choose to ignore.</li></ul><div class=""><br class=""></div><div class="">So a method with @super is equivalent to @super(optional), while a method with a plain @super attribute is equivalent to @super(required, error)</div><div class=""><br class=""></div><div class="">I really like the idea of using override(before) at the call-site as a shorthand for having the super call as the first statement behind the scenes, and likewise for final(after).</div><div class=""><br class=""></div><div class="">However, with regards to a plain override, I think it should still be permitted, but the compiler will check for the presence of the super call, and that it meets the criteria specified (if any). One further caveat is that non-mutating statements (or pure functions?) should be permitted somehow, alone with simple statements, as this allows variables to be prepared, log-entries created etc. without breaking the super requirement. So for example you could do:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>class Foo { @super(before) func someMethod(foo:T) {} }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>class Bar extends Foo {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>override func someMethod(foo:T) {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>var foo = foo</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>print(foo)</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>mutateFooViaInout(foo) // This is a non-mutating or pure function that changes its input via inout</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>super.someMethod(foo) // This is still the start as far as @super(before) is concerned</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div class=""><br class=""></div><div class="">Part of the problem with this is that it's difficult to add the flexibility required for classes, since they don't have the concept of mutating/non-mutating; so this means we'd have to wait for that to be added and/or detection of pure functions (unless it's easy to detect already, I don't know), otherwise the @super(before) and @super(after) conditions may be too restrictive, and have to be delayed till later.</div><div class=""><br class=""></div><div class="">The main remaining argument was whether it is possible for the API designer to get the before/after requirement right, but then this is why I suggest the ability to make it a warning rather than an error (it could even be the default if people prefer). But I think in general API designers shouldn't add a @super attribute unless they know with certainty what they need from their design; for example if properties aren't properly instantiated/loaded unless the super method is called first, then that's a good reason to user @super(before), if there are a bunch of private properties that <b class="">must</b>&nbsp;be kept up-to-date then @super(required) and so-on.</div><div class=""><br class=""></div><div class="">Otherwise if the API designer specifies nothing, we still get a nice addition to override at the call-site to remove a little boiler-plate and keep our sub-class methods clean.</div></div></body></html>