Franciszek Czekała:

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.

Surely there are more important things to care about. But a non-null system has right the purpose of allowing you to take more care of the program logic and less about possible null values.


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

A well implemented not-nullable system forces you to verify the possible presence of null of nullable values. And if you handle the null value in a "if" clause then the compiler will assume the reference is not null in the other clause. This essentially means the type of that reference is different inside the two clauses.

A small program that shows two or three important things std.typecons.Nullable isn't able to do:


import std.stdio, std.algorithm, std.typecons;

alias Nullable!(int, -1) Position;

void foo(int[] a, Position pos) /*nothrow*/ { // allow this to be nothrow
    if (pos.isNull) {
        return;
    } else {
a[pos] = 10; // perform no nullness test here, optimization
    }
}

void bar(int[] a, Position pos) {
    a[pos] = 10; // maybe: require a test here?
}

void main() {
    auto data = [1, 2, 3, 4, 5];
    auto p = Position(countUntil(data, 7));
    foo(data, p);
    writeln(data);
}


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.

Even better: avoid similar problems statically, with a not-nullable extension of the type system, so there is no need to debug your program after a run.


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 D programs contain prime number classes as often as not-null references then adding a syntax to statically rule out not-prime numbers is an acceptable idea. But the initial assumption is false. Walter&Andrei have added @disable to try to allow programmers to disallow the presence of divisible numbers inside instances of a prime class too. But I am not sure the final result is good enough.


To quote (loosely) Mr. Walter Bright from another discussion: how many current bugs in dmd are related to default null references?

DMD source code is a compiler, it's not representative of all kinds of D programs. I think there is a class of commercial programs, or pointer-heavy programs that enjoy having not-null references.

Even if null-related bugs are not common in D code, having a language help you reduce one class of bugs helps you program faster. I am sometimes able to write working (and almost "correct") C programs, but D safeties allows me to write them faster. If you ask to Scala programmers they will tell you they are quite happy to not have to worry much about nulls when they write idiomatic Scala code, while they will tell you they have to keep more care when they inter-operate with Java code that sometimes has nulls.

Bye,
bearophile

Reply via email to