On Wednesday, 19 October 2022 at 13:17:00 UTC, Paul Backus wrote:
> On Wednesday, 19 October 2022 at 08:35:21 UTC, mw wrote:
> On Wednesday, 19 October 2022 at 08:29:20 UTC, mw wrote:
> OK, I saw what they are talking about.
Basically, in Eiffel, all query @mustuse.
Here in D @mustuse is an remedy add-on, which can be specified by the programmers in the middle of the inheritance tree, the question is what if the pointers got casted either upwards or downwards?
(It's too late for me here today.)
My gut feeling is: make it simple, if a method is marked as @mustuse anywhere in the inheritance tree, that method in all the class levels of the inheritance tree became @mustuse!
The correct rule is exactly what Mike quoted from my email discussion with Walter: implicit conversions may add @mustuse
, but can never remove it.
From this, it follows that
- a
@mustuse
method cannot override a non-@mustuse
method.
- a
@mustuse
class/interface cannot inherit from a non-@mustuse
class/interface.
In other words, you cannot introduce @mustuse
in a derived class; it must be present in the base class.
Let's concentrate on only @mustuse as a function attribute for now, since I have not checked the exact semantics of @mustuse as a type annotation.
There are two directions to propagate the attribute in the inheritance tree, upwards and downwards. We all agree on the direction of downwards propagation to the derived class methods, I.e in your expression: "may add @mustuse
, but can never remove it".
Now I only need to convince you the other direction to upwards is also needed:
It's actually quite simple, let us consider the original example which started this discussion, and do this exercise:
class AbstractPaths {
AbstractPaths remove (int I) {...}
}
class Paths : AbstractPaths {
@mustuse
AbstractPaths remove (int I) {...}
}
AbstractPaths absPaths = new Paths();
absPaths.remove(i); // shall @mustuse be enforced here on absPaths?
Let's step back, and ask why we want to introduce @mustuse in the beginning?
The purpose of the annotation is to help programmers do not discard important return values accidentally as what the OP's author has experienced disaster.
Then the answer is very clear: we do want @mustuse be enforced on the absPaths.remove(i) call in the above example!
Otherwise, it will be a loophole in the @mustuse as a function attribute logic, which defeat its purpose.
Convinced?
And as a consequence, all the AbstractPaths' derived classes' remove(i) method now must have this annotation ( injected by the D compiler, the programmer does not have to manually add it in all the places). That is why I say:
if a method is marked as @mustuse anywhere in the inheritance tree, that method in all the class levels in the whole inheritance tree became @mustuse!