> On 16 Nov 2016, at 22:37, Sean Heber via swift-evolution
> <[email protected]> wrote:
>
> That could be kind of neat - perhaps a syntax more like this so that there
> isn’t another bare keyword:
>
> override(after) func viewDidLoad() {
> }
>
> and:
>
> override(before) func viewDidLoad() {
> }
>
> 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):
>
> override func viewDidLoad() {
> // stuff
> super.viewDidLoad()
> // more stuff
> }
>
>
> A potentially neat thing about this is that you could possibly then impose
> restrictions on subclasses like so:
>
> final(before) func viewDidLoad() {}
>
> Which could mean that the “before” slot is “final” - therefore you cannot do
> either of these:
>
> override func viewDidLoad() {}
> override(before) func viewDidLoad() {}
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.
Basically the idea was that the parent method would have a @super() attribute
with of the following attributes available to use within it:
before: super must be called before all other statements in an overriding
method's body.
required: 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.
optional: the super call is not required.
after: super must be called after all other statements in an overriding
method's body.
error: failing to call the super method either at all or in the correct
location is an error. This is the default.
warning: failing to call the super method either at all or in the correct
location is a warning that a developer may choose to ignore.
So a method with @super is equivalent to @super(optional), while a method with
a plain @super attribute is equivalent to @super(required, error)
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).
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:
class Foo { @super(before) func someMethod(foo:T) {} }
class Bar extends Foo {
override func someMethod(foo:T) {
var foo = foo
print(foo)
mutateFooViaInout(foo) // This is a non-mutating or
pure function that changes its input via inout
super.someMethod(foo) // This is still the start as far
as @super(before) is concerned
}
}
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.
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 must be kept up-to-date then
@super(required) and so-on.
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._______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution