A
Arved Sandstrom
I agree with the statements above, sure. The problem we have is thatThe JLS does not defined »String value«, so you are all free to
define it as you like to. However, we also have
!( null instanceof java.lang.String )
. Since the objects of a value class are intended to model the
values modulo »equals«, not being an instance of such a class
has some weight in favor of not being a value of that model.
Albeit in some other context, the JLS says with regard to
Annotations,
»Note that null is not a legal element value for any
element type.«
null surely is a /reference value/, but it does not identify
a string value in the sense of the class String as a class
whose instances model string values.
'instanceof', say, indicates that 'null' is not an instance of a
reference type like String. But we also have that Java variables of
reference type can be assigned the value 'null' (implicit typecast).
So we end up with a situation where IMHO it's probably advisable not to
try making too much sense of it. The language mechanics have placed us
in the position of accepting that one special value that you can assign
to variables of reference type is _not_ an instance of any reference
type, but can be somehow implicitly typecast to any reference type. If
one ventures (perhaps too far) down this road, one might ask, what is
the implicit special value of String that null is implicitly typecast
_to_, that is nonetheless not an instanceof String?
Down that road lies madness. Hence the JLS' suggestion that programmers
treat null as a special literal that *can be of any reference type*. And
so I treat it, regardless of the behaviour of 'instanceof'.
We also have the difficulty in Java that 'null' appears - frequently -
as a working - albeit "special" - value of reference variables in
programs. People use it to mean uninitialized, unknown, a termination
condition, and I return also to the fact that 'null' is the *default*
value assigned to reference type variables.
Having said all this, let me revisit Option and Maybe. For me the
distinction to be drawn between the *semantics* of Option/Maybe and the
nullability of Java reference-type variables is probably one of degree,
not kind. So I regret using the word "qualitatively" in my previous
post; I'm not sure what word I prefer in its stead . Option/Maybe are
clean and unambiguous types that represent, by design, optional values
of some contained type. The interpretation of 'null' in Java is not so
clean. Furthermore, I can use == and != with 'null' in constructs like
"Arved" != null
just as easily as
"Arved" == "Bill"
which to me further blurs the perception that null is, or isn't,
_effectively_ a value of String or any other reference type. Again, the
JLS suggestion that we pretend that that's what 'null' is.
To return to Andreas' argument, it's certainly possible for any given
Java programmer to rigorously adhere to an interpretation of 'null' as
meaning None or Nothing. That would however be a personal choice; some
other programmer might not do that (it could be Unknown, or No Mapping
For Key X, or End Of Stream). Assuming that None/Nothing is the rigorous
interpretation of 'null' by said programmer, there is still no special
treatment for the 'null' value...we end up testing for it the same way
as we do for object instances. We test for it just like we do for any
other value, but arguably it's special. So special that it's not an
instance of any reference type except the null type.
So I'll stick to the main case, which is simply that Scala option and
Haskell Maybe are better ways of dealing with this notion. In fact so
would BoolStr (or BoolObj) be; Nigel's suggestion. In Java, as I've
expressed, I prefer exceptions anyway, but I absolutely don't like
'null' as a special value (of something) (*). The OP in any case said
that that latter approach will not be acceptable.
AHS
* I'll hold my nose and use it - Java makes it difficult not to.