<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=""><div class="">Woah, pretty expansive and well thought out set of rules here!</div><br class=""><div><blockquote type="cite" class=""><div class="">On 16 Feb 2016, at 03:36, Howard Lovatt &lt;<a href="mailto:howard.lovatt@gmail.com" class="">howard.lovatt@gmail.com</a>&gt; wrote:</div><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">&nbsp; &nbsp; 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 class=""></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 class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">&nbsp; &nbsp; 2. A function declaration requires one of `func`, `func(final)`, `func(replace)`, `func(option)`,&nbsp;`func(before)`, `func(after)`, or `func(instead)`&nbsp;keywords and a function override requires one of `override`, `override(final)`, `override(replace)`, `override(option)`,&nbsp;`override(before)`, `override(after)`, or `override(instead) - note no func keyword.</div></div></blockquote><div><br class=""></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 class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">&nbsp; &nbsp; 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 class=""></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 class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">&nbsp; &nbsp;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" class=""><div dir="ltr" class=""><div class="">&nbsp; &nbsp;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 class="">&nbsp; &nbsp;9. `override` is a shorthand for `override(A, final)` where A is the annotation specified in the matching `func` declaration.</div><div class="">&nbsp; &nbsp;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 class=""></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 class=""></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>class MyClass {</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>@super(required)</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>func mustCallMe() { … } // Immediate sub-classes must call this method</font></div><div><font face="Monaco" class=""><br class=""></font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>@super(optional)</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>func someOtherMethod() { … } // Call super, or not, this method doesn’t care</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div><font face="Monaco" class=""><br class=""></font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>class MySubClass : MyClass {</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>@super(before)</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>override func mustCallMe() { … } // Further sub-classes must now call this first</font></div><div><font face="Monaco" class=""><br class=""></font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>override func someOtherMethod() { … } <span class="Apple-tab-span" style="white-space:pre">        </span>// This implicitly agrees to optionally include the parent call and&nbsp;</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                                                        </span>//&nbsp;is final due to the lack of a @super attribute of its own (or one on its class).</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div><br class=""></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).&nbsp;</div><div><br class=""></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 class=""></div><div><ul class="MailOutline"><li class=""><b class="">required</b>: parent method must be called somewhere in all code paths of overriding method.</li><li class=""><b class="">optional</b>: parent method may or may not be called anywhere in the overriding method.</li><li class=""><b class="">replace</b>: parent method may not be called at all by overriding method (sub-class must provide total replacement).</li><li class=""><b class="">before</b> and <b class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>class MyClass {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>super(required) func mustCallMe() { … }</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="">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></body></html>