<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 17 Feb 2016, at 01:22, Brent Royal-Gordon &lt;<a href="mailto:brent@architechies.com" class="">brent@architechies.com</a>&gt; wrote:</div><div class=""><br class="">That's a serious problem for Swift resilience—it's not safe to change a public class from final to non-final because that would break devirtualized calls in other modules. Whatever the default is, it needs to not break things.<br class=""></div></blockquote><div><br class=""></div><div>Swift hasn’t really shied away from breaking things thus far, but this is partly why I mentioned supporting a class level override. So for example, if @super(optional) is the current behaviour (can override, compiler doesn’t care what you do) then that could be added to all existing classes in a project, but without it a new class will default to its methods being final.</div><br class=""><blockquote type="cite" class=""><div class="">- It conflates several different features—final, abstract, super call requirement, super call location—into a single set of annotations.<br class=""></div></blockquote><div><br class=""></div><div>Not quite; I’d say that abstract is kind of its own thing, but would definitely build in the addition of extension requirements. Regarding the rest, is them being in a single set of annotations actually a bad thing? IMO that’s an advantage, as plus it’s not like it should be complicated. In the sample set of annotations I gave you might do:</div><div><br class=""></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>@super(optional, before)</font></div><div><br class=""></div><div>Which essentially reads as “extending classes don’t need to include super call, but must place it first if they do”. The most major change is really that the final keyword wouldn’t be necessary except for classes that set @super(optional) as their default (as everything would be overridable otherwise). That said it probably does make sense to just make final another type of requirement for consistency in that case.</div><br class=""><blockquote type="cite" class=""><div class="">- It violates the usual grammar of Swift declarations by attaching particular modifiers directly to the keyword, disrupting the usual flow of modifiers-keyword-name-type.<br class=""></div></blockquote><div><br class=""></div><div>private(set) already does this, so super(optional, before) or whatever wouldn’t be any different. We’re considering other options like @attributes as well, but they’re functionally the same so it really comes down to code style.</div><br class=""><blockquote type="cite" class=""><div class="">- It not only supports, but actively encourages, placing extremely heavy constraints on subclass implementations. (Want to put a logging statement before a "before" method's super call or after an "after" method's? Too bad, the guy who wrote the superclass said "no”.)<br class=""></div></blockquote><div><br class=""></div><div>I wouldn’t say it encourages heavy constraints, in fact I’d expect most developers to mostly use required or optional. The before and after conditions make more sense in the case of abstract classes that are partial implementations specifically intended to be built upon in a certain way.</div><div><br class=""></div><div>It’s possible the restriction could be relaxed to allow non-mutating operations before/after the required statement, but I think in general developers shouldn’t be adding the before/after requirements unless they’re absolutely certain it has to be done that way. Technical you can still work around it like so:</div><div><br class=""></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>class Foo {</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>super(before) func doSomething() { … }</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>class Bar : Foo {</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>super(required) override func doSomething() {</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>super.doSomething(); // Foo decreed that this shall be so</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>…</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>class AddLogging : Bar {</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>override func doSomething() {</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>/* Do some logging here and there’s nothing Foo can do about it */</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                        </span>super.doSomething()</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>}</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div><br class=""></div><div>Not pretty I know, but the point is that you aren’t actually completely prevented, but you should have a good reason to want to do this if it circumvents what a developer set as an explicit requirement. In the case of Foo being abstract however this actually makes a lot of sense, as Bar would be the first proper implementation, so has to follow all the rules, but relaxing them afterwards is fine.</div><br class=""><blockquote type="cite" class=""><div class="">In general, this proposal seems like it's tremendously overengineered, insufficiently motivated, and fits poorly into Swift's syntax.</div></blockquote><br class=""></div><div>I don’t think the guts are actually that complex, the syntax just needs to be paired down to basics, and abstract classes possibly added later once the groundwork is done.</div></body></html>