-
Notifications
You must be signed in to change notification settings - Fork 1.7k
"Null check operator used on a null value" error message should use better terminology #47185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I suppose while I'm nitpicking the terminology, while I prefer "null assertion operator" over "null check operator", I'm not a huge fan of "null assertion operator" either. Assertions assert that a condition is true, so "null assertion operator" implies to me that something is null. IMO "non-null assertion operator" would be better. But even then, assertions are typically conditionally enabled, so my ideal preference would be something like "null failure operator" or "non-null cast operator". |
The null-safety specification, in the section on runtime semantics, includes the following
This implies that there is, in fact, a runtime check involved with the use of the operator, so I believe that the word "check" is conveying the correct semantics. |
I don't dispute that it performs a runtime check nor that that's how the specification refers to it; I'm saying that the term is confusing and makes it harder to explain to new users what they're doing wrong. Calling it a "null check" is not useful because it introduces ambiguity. Each of the following things can be called a "null check", but one of them is not like the others:
|
The specification uses the phrase 'type check' about expressions of the form We could use that as a starting point for the bang selector: It may seem overly pedantic to call it a 'selector' (because that word might not be very familiar to some developers who would consider 'operator' to be an obvious choice), but it does give more precise hints about the semantics. For instance, |
I'm not aware of any user studies that have been done on terminology (though that might be useful), but I suspect that very few users will understand the word "selector". As far as I can tell, the term "selector" is only used to mean "CSS selector" on I'm ok with calling it a "non-null check [operator]" and will be happy to update messages and documentation for the analyzer to use that terminology if that's what we're settling on. |
|
The import 'dart:async';
void main() {
FutureOr<int?> x = 1 as dynamic; // The cast just ensures that we don't promote `x` to `int` here.
...
foo(x!); // For some reason we insist that `x` isn't null at this point.
} There is no type I don't really see why it should be misleading or confusing to call it a 'non-null check': A 'check' is an operation that may fail or succeed, and if it fails then we get a dynamic error. That error is specified to be the act of throwing an object, so even though it is bad style then it is not impossible to catch it, which is a property that it shares with other dynamic errors. If the check succeeds then it is transparent (that is, everything behaves as if the check never occurred). Granted, I might consider this terminology normal and unsurprising because that's the terminology we have used in the specification for many years when it comes to type checks (that is,
But it wouldn't work that way, there is no "check that It might be confusing that we can use |
That's a good example, but I still think it'd be fair to call it the "non-null cast operator". (I also still like "null failure operator".)
I recall being told that for some optimization levels when compiling to JavaScript that (some?)
You have the perspective of someone who is already intimately familiar with the language. I'm talking about people who very much aren't, who sprinkle in While "check" is technically correct, I don't think it does us any favors. It's broad and ambiguous; there are other operators that check whether a value is null, and I don't think that using a definite article is an obvious distinction. |
I agree, of course, that we need to be careful about the terminology, and also that it's important to strive for consistency. Dictionary definitions of 'check' include examine (something) in order to determine its accuracy, quality, or condition, or to detect the presence of something and to make certain that something or someone is correct, safe, or suitable by examining it, him, or her quickly. They both fit the framework of (1) performing a measurement, and (2) comparing the given outcome with an expected outcome. They leave it implicit what happens if the outcome isn't as expected, but I think it's reasonable to say that it is a failure of sorts. 'Assertion' is actually better than 'check' because it very directly implies that there is a measurement with a certain expected outcome, and any different outcome is a failure. But I bought the argument that 'assertion' in Dart almost exclusively refers to the language construct 'Check' then seems to be a reasonable choice, and it seems to support the underlying structure "OK => just continue" vs. "ERROR => throw". @jamesderlin wrote:
When I said:
I was just responding to your remark
in your definition of a 'check'. Dart check failures are always throwing, so they can always be caught. A low-level error like BUS_ERROR or SEGMENTATION_FAULT only occurs if we encounter a bug in the implementation of Dart. So I did not accept your premise that a check failure is always fatal. ASIDE:
Let's consider those other operators a bit:
|
@eernstg While everything you've written is technically correct, I'm not convinced that it is the best kind of correct. My desire was to use terminology less vague than "check" to make things less confusing for people learning Dart. Those people almost certainly will not do the careful and thoughtful analysis that you've done. (If they did, they wouldn't be misusing That Since |
@jamesderlin, it is true that But if you really, really don't like the word 'check', and we agree that 'assertion' is already taken, is there a better word? ;-) |
In a different thread about the message for a different diagnostic, I suggested that we could eliminate the question of terminology by re-writing the message completely rather than by attempting to fix one phrase. That might be a useful approach here as well. What if the message were more like: "A value that was expected to not be null was null."? (We could probably find something even better, but it illustrates one wording that eliminates the need to have a name for the |
I'd personally prefer to have a name that's clearer for the 99% use case than to make it worse 99% of the time to accommodate a 1% case.
I'd be satisfied with that. |
Steps to reproduce:
Result:
I dislike that this error message refers to postfix
!
as the "Null check operator":null
.I think that the error message instead should be: "Null assertion operator used on a null value".
I'm using: Dart SDK version: 2.14.1 (stable) (Unknown timestamp) on "linux_x64".
The text was updated successfully, but these errors were encountered: