[swift-evolution] [Idea] Extend "required" to methods other than init()

Matthew Johnson matthew at anandabits.com
Wed Jan 20 20:45:08 CST 2016


> On Jan 20, 2016, at 8:20 PM, Howard Lovatt <howard.lovatt at gmail.com> wrote:
> 
> Adding protected access and abstract methods and classes might be easier, since then you could do:
> 
> /* abstract */ class Base {
>     /* protected abstract */ func methodToBeOverridden() -> String { fatalError("Abstract") }
>     final func controlsWhenOverrideIsCalled() -> String{
>         var s = "In 'super' before override call.\n"
>         s += methodToBeOverridden()
>         return s + ".\nIn 'super' after override call."
>     }
> }
> 
> class Derived: Base {
>     /* protected */ override func methodToBeOverridden() -> String {
>         return "In override"
>     }
> }
> 
> let d = Derived()
> d.controlsWhenOverrideIsCalled()
> 
> Which results in:
> 
> In 'super' before override call.
> In override.
> In 'super' after override call.
> 
> Calls to super could then be eliminated from the language!

Not really.  This covers some use cases but by no means all of them.  It also adds complexity to the design (by introducing two names).  

Aside from that, we are not going to see `protected` access control in Swift.  It does not fit the access control model of the language, which is scope-based rather than type-based.  This is a good thing IMO.

-Matthew

> 
> On 21 January 2016 at 11:53, Jesse Squires <jesse.d.squires at gmail.com <mailto:jesse.d.squires at gmail.com>> wrote:
> Thanks Matthew and Howard! A lot of good points there.
> 
> There are certainly a few more possible semantics for overrides than I was initially thinking. It’s not clear to me if the language should support each use case or not. Doing so seems to add unnecessary complexity for (potentially) little gain.
> 
> I can’t say for sure, but my guess is that the *most common* scenario is: "if a method is overridden, it must call super first". This would also make automatically synthesizing the call to super simpler, which I think is a great idea. Clients then have less of a burden when subclassing.
> However, as noted, non-void returns complicate this. Also, I agree that re-purposing `required` could be confusing. I’m open to ideas for an alternative keyword.
> 
> Again, a lot of good ideas/feedback. I’m actually not sure where this leaves us. :) Accounting for all of the possible semantics seems too complex and burdensome, though I think our current state is insufficient. And perhaps accounting for only the simplest scenario, "if a method is overridden, it must call super first", would only further highlight the lack of ability to express the other possible semantics.
> 
> ¯\_(ツ)_/¯  I’d love to hear if anyone else has ideas or shares these concerns!
> 
> Jesse
> 
> 
> > On Jan 18, 2016, at 11:34 AM, Howard Lovatt via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> >
> >>>
> >>> Are there other languages worth investigating which have the requires super first/last semantics you note?
> >>
> >> I don’t know of any languages that support this.  It is not the most common semantic, but when it occurs it seems important enough that it would be better if it could be specified in the language itself and enforced rather than left to documentation.
> >
> > BETA has this ability, but it worked rather differently than modern OO languages (which work more like its predecessor Simula). In BETA you can only ever call the top most method, it can then optionally call the immediately overriding method. The syntax BETA uses is `inner(<args>)`. Probably easier with examples (in BETArised Swift):
> >
> >    class Base {
> >        func finalM() { print("finalM") }
> >        func mustOverrideM() {
> >            print("beforeInner")
> >            inner()
> >            print("afterInner")
> >        }
> >    }
> >
> >    class Derived: Base {
> >        func mustOverrideM() {
> >            print("inInner")
> >        }
> >    }
> >
> > Methods `finalM` and `Derived.mustOverrideM` are automatically final because they do not call inner.
> >
> > You can't make an instance of `Base` because method `Base.mustOverrideM` needs to be overridden, i.e. `Base` is automatically abstract.
> >
> > If you:
> >
> >    let d = Derived()
> >    d.mustBeOverriddenM()
> >
> > Then it prints:
> >
> >    beforeInner
> >    inInner
> >    afterInner
> >
> > _______________________________________________
> > swift-evolution mailing list
> > swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> > https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
> 
> 
> -- 
>   -- Howard.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160120/8fc5b3c6/attachment.html>


More information about the swift-evolution mailing list