I've often wondered why languages with a null
representing "no value" don't differentiate between the passive "I don't know what the value is" and the more assertive "There is no value.".
There have been several cases where I'd have liked to differentiate between the two (especially when working with user-input and databases).
I imagine the following, where we name the two states unknown
and null
:
var apple;
while (apple is unknown)
{
askForApple();
}
if (apple is null)
{
sulk();
}
else
{
eatApple(apple);
}
Obviously, we can get away without it by manually storing the state somwhere else, but we can do that for nulls too.
So, if we can have one null
, why can't we have two?
Note
null
is an acceptable, yet known condition. An unknown state is a different thing IMO. My conversation with Dan in the comments' section of the top post will clarify my position. Thanks Dan!.What you probably want to query is whether the object was initialized or not.
Actionscript has such a thing (
null
andundefined
). With some restrictions however.See documentation:
It's because Null is an artifact of the language you're using, not a programmer convenience. It describes a naturally occurring state of the object in the context in which it is being used.
In .net langages, you can use nullable types, which address this problem for value types.
The problem remains, however, for reference types. Since there's no such thing as pointers in .net (at least in 'safe' blocks), "object? o" won't compile.
I think having one NULL is a lower-common denominator to deal with the basic pattern
In the "do something else" part, there are a wide range of possibilities from "okay, forget it" to trying to get "thing" somewhere else. If you don't simply ignore something that's NULL, you probably need to know why "thing" was NULL. Having multiple types of NULL, would help you answering that question, but the possible answers are numerous as hinted in the other answers here. The missing thing could be simply a bug, it could be an error when trying to get it, it may not be available right now, and so on. To decide which cases apply to your code -- which means you have to handle them -- it domain specific. So it's better to use an application defined mechanism to encode these reasons instead of finding a language feature that tries to deal with all of them.
Some people will argue that we should be rid of
null
altogether, which seems fairly valid. After all, why stop at two nulls? Why not three or four and so on, each representing a "no value" state?Imagine this, with
refused
,null
,invalid
:First you check if you have the apple info, later you check if there is an apple or not. You don't need different native language support for that, just use the right classes.