On Wednesday, 3 October 2012 at 17:37:14 UTC, Franciszek Czekała
wrote:
No, it is meaningless. If you have a class which is supposed to
hold a prime number and you pass it to a function are you going
to check each time that the value is indeed prime? That would
kill the efficiency of your program guaranteed. So you would be
happy to know that the reference is non-null but you would take
it for granted the value is indeed prime? Does it make any
sense?
You have to decide which information should be available at
compile- and runtime. And that is not easy. In general, it's
always better to have information present at compile time. To
come back to your example:
class Number {
this(int i) {
this.i = i;
}
const int i;
}
class PrimeNumber : Number {
this(int i) {
// Check whether i is a prime number or not...
....
super(i);
}
}
void func(PrimeNumber num);
That's a way to check this at compile time and pass the number
without runtime checks between prime number functions. But it
requires i to be constant throughout the lifetime of Number.
It always depends on the context if the use of an extra class
makes sense.
I maintain that this non-null "advantage" does not warrant to
make the language more complicated even by a tiny bit. It is
dwarfed by normal considerations related to program correctness.
With default null references:
A)either null is an expected non-value for the type (like in
the chess example), checking for it is part of normal
processing then
Great, use a question mark.
B) or null is not a valid value, then there is no need to check
for it. If you get a null reference it is a bug. It is like
getting a 15 for your prime number. You do not put checks like
that in your code. You test your prime generation routine not
the consumers. If your function gets a null reference when it
should not, some other part of your program is buggy. You do
not process bugs in your code - you remove them from it.
Contract programming comes into play. But still, you have to
write contracts containing all those assertions. In libraries you
can't even use contracts in most cases.
However with D, dereferencing an uninitialized reference is
well defined - null is not random data: you get a well-defined
exception and you know you are dealing with unitialized data.
This is easy to fix. You just go up the stack and check where
the reference comes from. Much easier probably than finding out
why your prime numbers turn out to be divisible by 3. How about
introducing some syntax that will rule this out?
If you write an application, indeed, it's easy to fix.
To quote (loosely) Mr. Walter Bright from another discussion:
how many current bugs in dmd are related to default null
references?
DMD is an application, not a library.