Feedback Thread: DIP 1038-- at nodiscard--Final Review
Paul Backus
snarwin at gmail.com
Thu Feb 4 14:17:35 UTC 2021
On Thursday, 4 February 2021 at 09:09:02 UTC, Walter Bright wrote:
> 1. > Note that the former is a syntax-level check, while the
> latter is a type-level check. This means that the value
> returned from a @nodiscard function may in fact be discarded as
> long as the function call itself is enclosed in some other
> expression.
>
> These two sentences do not make sense together. The second
> sentence only refers to the syntax-level check.
I intended "a @nodiscard function" to refer only to the
syntax-level check, but I can see how it can be read as
ambiguous. A clearer way to phrase it would be "a function
annotated with @nodiscard."
> 2. Consider:
>
> @nodiscard int foo();
> a ? b : foo();
>
> discards the return result of foo(), but according to the DIP
> no error will be detected. This is another case of the comma
> expression one mentioned in the Description.
>
> This is a critical shortcoming in the DIP that needs to be
> addressed. Perhaps this feature in other languages can provide
> guidance.
This is exactly how the feature works in GCC, Clang, C++17, and
Rust.
We have a name for information about an expression that
propagates, transitively, from sub-expressions to
super-expressions the way you suggest @nodiscard ought to
propagate. We call it the expression's "type." So what you are
suggesting here, in effect, is that @nodiscard should become a
type qualifier, and that we should write
@nodiscard(int) foo();
While this would indeed detect an error in cases like the one you
give above, there are second-order effects to making `T` and
`@nodiscard(T)` distinct types. For example:
@nodiscard(int) foo();
int bar()
auto a = foo();
auto b = bar();
b = a; // Error: cannot implicitly convert `@nodiscard(int)`
to `int`
This kind of error is obviously not going to help anybody catch
bugs in their code--it is pure noise.
If the syntax-level check is deemed inadequate, I think the best
way to proceed is to simply remove it from the DIP and include
only the type-level check (this is what Rust did, originally).
But I think it's important to keep in mind that there is no
perfect solution here, only tradeoffs.
More information about the Digitalmars-d
mailing list