Andrei Alexandrescu wrote:
Walter Bright wrote:
Daniel Keep wrote:
I need to know when that null gets stored, not when my code trips over
it and explodes later down the line.

Ok, I see the difference, but I've rarely had any trouble finding out where the assignment happened. In fact, I can't remember ever having a problem finding that.

That's because the null pointer exception is nearly always repeatable, so it isn't hard to work backwards. The non-repeatable ones have been due to memory corruption, which is a different issue entirely.

The world is more diverse than one environment. When I run 200 jobs on a cluster, failure from null pointer usage comes back with no file and line information, no debugger nicely starting, no nothing. And it's not easy to reproduce that on a small machine with GUI and all.

Non-nullable types (or proxy struct or whatever) means the code won't
even compile if there's an untested path.  And if we do try to assign a
null, we get an exception at THAT moment, so we can trace back to find
out where it came from.

Yes, I understand that detecting bugs at compile time is better. But there's a downside to this. Every reference type will have two subtypes - a nullable and a non-nullable. We already have const, immutable and shared. Throwing another attribute into the mix is not insignificant. Each one exponentially increases the combinations of types, their conversions from one to the other, overloading rules, etc.

Andrei suggests making a library type work for this rather than a language attribute, but it's still an extra thing that will have to be specified everywhere where used.

There are a lot of optional attributes that can be applied to reference types. At what point is the additional complexity not worth the gain?

The added language complexity is very small and not visible to the user. You change the default behavior. The library takes care of the rest. Non-null is not const, not invariant, not shared, and should not be compared in cost and benefits with them.

And there is no reference type with two subtypes. It's one type in the language and one in the library. Maybe-null (the library) is a supertype of non-null (the default).

One problem I can see is with extern(C),(Windows) functions, since pointers are maybe-null in C. The name-mangling has to work out. I can't see how this can be done without the compiler knowing SOMETHING about both nullable and non-nullable types. At the bare minimum, you need to deal with maybe-null returns and reference parameters from C functions.

Incidentally, uses of maybe-null in immutable types must be _extremely_ rare. The usage statistics for D are likely to be skewed towards non-null types, compared to Java. I'd say the 66% is a very conservative lower bound.

Again: there is no "adding" to the language. It's changing. You don't need to even look at overloading, combinations etc. All you need to look at is constructors. (Oh, Bartosz and I found a couple of other bugs in constructors last night too.)


Andrei

Reply via email to