I'm not convinced this is needed. If it gets added, I think it should be a warning, not an error, and should offers a way to silence the warning, similar to how ignoring a return value results in a warning today. But if it goes forward, here are some point that deserve more thought.
The ability to specify whether you want the call to super to happen at the end doesn't make sense to me. It's actually quite ambiguous what it means. Take this simple function:
func test(with string: String) {
let newString = string + "some suffix"
super.test(with: newString)
}
Now, you might think the last thing the function does is calling super.test(with: newString)
, but that is not actually the case. The last thing this function does is decrementing the reference counter for newString
's storage, and possibly deallocating the storage.
In reality, it's pretty common to have some cleanup operations at the end of a function call. That cleanup can end up calling arbitrary code (think of defer
or class's deinit
). And while you could try to specify which kind of cleanup code is allowed and which isn't, I doubt it is possible define something useful.
You could disallow cleanup from happening after the supercall (which would also guaranty a tail call optimization), but then trivial code like the example above will not compile for reasons that could appear quite obscure.
Similarly, making it an error to not call the superclass's implementation will break patterns that rely on calling it indirectly from another function. That might seem a weird thing to do, but think about how you sometime wrap code in closures:
func moveUp() {
UIView.animate(withDuration: 0.2) {
super.moveUp()
}
}
While you know the closure is called once and only once, the compiler doesn't. It will have to emit an error if the superclass implementation had this requirement about calling it in the overridden implementation.
And this is an interesting problem because of its similarity: the animate
method must call the closure you pass to it exactly one time, much the same way you want the superclass' implementation of your method to be called exactly one time. Perhaps there is something to generalize here so it can apply to every case where a function must call another one exactly one time.