@Haravikk,<div><br></div><div>I am not perticularly fussed about the exact syntax so long as it is clear and consistent, it is the semantics I am most interested in. I would say just go with what is the most popular syntax. The syntax I suggested is clear, consistent, and concise, that is why I suggested it, EG instead of:</div><div><br></div><div>    @super(option) override func name() { ... }</div><div><br></div><div>I am suggesting</div><div><br></div><div>    override(option) name() { ... }</div><div><br></div><div>Its only syntax :). Either is fine because they are both clear and consistent.</div><div><br></div><div>Changing tack to abstract methods and classes. Maybe it is necessary to propose abstract methods and classes for Swift with a future expansion section noting that it is the intention to add control over when super is called at a later date and giving some examples. That way abstract classes can be added with systax that can be extended to accommodate more control at a later date. The problem with doing two seperate proposals is that the syntax could become inconsistent.</div><div><br></div><div>Thanks for starting this thread, I think it would be a valuable addition to Swift.</div><div><br></div><div> -- Howard.<br><br>On Wednesday, 17 February 2016, Haravikk &lt;<a href="mailto:swift-evolution@haravikk.me">swift-evolution@haravikk.me</a>&gt; 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"><div>Woah, pretty expansive and well thought out set of rules here!</div><br><div><blockquote type="cite"><div>On 16 Feb 2016, at 03:36, Howard Lovatt &lt;<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;howard.lovatt@gmail.com&#39;);" target="_blank">howard.lovatt@gmail.com</a>&gt; wrote:</div><div><div dir="ltr"><div><br></div><div>    1. Make methods and classes final by default and mark an overridable class with `class(option)` or `class(replace)` (see below for `class(replace)`).</div></div></div></blockquote><div><br></div><div>This is a great idea, it’s definitely better to force the developer to think about extension and explicitly declare it, and having the whole thing self-documenting will make it so much easier.</div><br><blockquote type="cite"><div dir="ltr"><div>    2. A function declaration requires one of `func`, `func(final)`, `func(replace)`, `func(option)`, `func(before)`, `func(after)`, or `func(instead)` keywords and a function override requires one of `override`, `override(final)`, `override(replace)`, `override(option)`, `override(before)`, `override(after)`, or `override(instead) - note no func keyword.</div></div></blockquote><div><br></div><div>I’m not so sure about putting this into the keywords. Personally I think an attribute is a bit neater (it can go nicely above the function declaration). Meanwhile with override I think it’s probably enough to just override a method, as this implicitly agrees to whatever rules were set out by the super-method. If want to put your own requirements on sub-classes even further down the chain then you just add the attribute to your own method.</div><br><blockquote type="cite"><div dir="ltr"><div>    6. A class with a method without a body, which must be marked `func/override` or `func/override(replace)`, has to be marked `class(replace)`; it is abstract. (Note the notation `class(option)` and `class(replace)` is consistent, a `class(option)` has at least one optionally overridable method and no `func/override(replace)` methods, whereas a class with at least one `func/override(replace)` method is marked `class(replace)`.)</div></div></blockquote><div><br></div><div>I like this, but would an abstract keyword not be simpler and clearer to most? Setting it on a class would allow that class to contain abstract methods (and properties?) also declared with the abstract keyword. An abstract method could contain no body (child class must give full implementation) or could include a body in which case it must be extended and called.</div><br><blockquote type="cite"><div dir="ltr"><div>   7. Any of the annotations can be extended with final, e.g. `func(optional, final)` means it is overriding a `func(optional)` but from this point down it is final. Final methods must have a body.</div></div></blockquote><blockquote type="cite"><div dir="ltr"><div>   8. In a class/protocol `func` is shorthand for `func(final)` unless the method has no body in which case it is shorthand for `func(replace)`.</div><div>   9. `override` is a shorthand for `override(A, final)` where A is the annotation specified in the matching `func` declaration.</div><div>   10. Overriding methods in a final class do not require the extra final annotation, e.g. in a final class `func(option)` and `func(option, final)` are equivalent.</div></div></blockquote><br></div><div>I think my preference is still towards an attribute to specify the requirements for sub-classes overriding a method, with the override keyword implicitly agreeing to those conditions rather than having to repeat them. If you want to change those requirements for further levels of sub-class then you can just add the same attribute your own methods, like so:</div><div><br></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>class MyClass {</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>@super(required)</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>func mustCallMe() { … } // Immediate sub-classes must call this method</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>@super(optional)</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>func someOtherMethod() { … } // Call super, or not, this method doesn’t care</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>}</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>class MySubClass : MyClass {</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>@super(before)</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>override func mustCallMe() { … } // Further sub-classes must now call this first</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>override func someOtherMethod() { … } <span style="white-space:pre-wrap">        </span>// This implicitly agrees to optionally include the parent call and </font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                                                        </span>// is final due to the lack of a @super attribute of its own (or one on its class).</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>}</font></div><div><br></div><div>If an overriding method has no @super attribute of its own then it is implicitly final, unless the attribute is instead placed on the class (allowing us to make a class’ methods all overridable if we like). </div><div><br></div><div>I dunno, it may just be personal preference; I can completely get wanting to clarify what rules are being followed at each step, but I’m just unsure whether the extra complexity is worth it? I can definitely see the need to introduce more options over the three I gave though, giving us:</div><div><br></div><div><ul><li><b>required</b>: parent method must be called somewhere in all code paths of overriding method.</li><li><b>optional</b>: parent method may or may not be called anywhere in the overriding method.</li><li><b>replace</b>: parent method may not be called at all by overriding method (sub-class must provide total replacement).</li><li><b>before</b> and <b>after</b>: these imply required but can also be set as optional (to be read as “if included, parent call must come first/last”). Not sure if after should require the parent method’s return value to be used in methods with a return type?</li></ul><div><br></div><div>I think that abstract methods and classes should probably be a separate proposal building upon these extension requirements. In essence though an abstract method with no body would imply @super(replace). An abstract method with a body implies @super(required), but could anything other than @super(replace) would be valid, allowing an abstract class to provide a sample implementation that need not be used in sub-classes, optionally setting a before/after requirement in the event that it is used.</div><div><br></div><div>Thoughts? I’m not too fussy about the exact syntax, but I think that while repeating the requirements in the override is explicit (which is usually a good thing) I personally think that the override keyword alone should suffice, as anyone creating a sub-class should know what the requirements of the parent are and agreed to them. What’s important is really whether the overriding method itself has any requirements for classes further down the hierarchy I think.</div><div><br></div><div>I also think it could be interesting to allow @super on the class itself, allowing the developer to decide if they want to keep the implicitly final default, or make their methods implicitly overridable, in which case they can then use the final keyword to put it back again.</div><div><br></div><div>Lastly, I’m not sure about the use of an attribute actually as I’m not clear on what the rules for them really are (if there are any?). I quite like how they look and they’re already setup to support multiple options etc., but adding options to a keyword may make sense. If we do that though then personally I think we could just re-use super, e.g-:</div><div><br></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>class MyClass {</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>super(required) func mustCallMe() { … }</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>}</font></div><div><br></div><div>I suppose there’s no reason this couldn’t go on func() like you suggest, but I like the consistency with the fact that it’s the super keyword in the method body that this feature is controlling.</div></div></div></blockquote></div><br><br>-- <br>-- Howard.<br>