Null references redux

Jeremie Pelletier jeremiep at gmail.com
Tue Sep 29 07:23:49 PDT 2009


Derek Parnell wrote:
> On Mon, 28 Sep 2009 19:27:03 -0500, Andrei Alexandrescu wrote:
> 
>> language_fan wrote:
>>>   int min;
>>>
>>>   foreach(int value; list)
>>>     if (value < min) min = value;
>>>
>>> Oops, you forgot to define a flag variable or initialize to int.min
>> You mean int.max :o).
> 
>   if (list.length == 0)
>      throw( some exception); // An empty or null list has no minimum
>   int min = list[0]; 
>   foreach(int value; list[1..$])
>     if (value < min) min = value;
> 
> 
> I'm still surprised by Walter's stance.
> 
> For the purposes of this discussion...
> * Null only applies to the memory address portion of reference types and
> not to value types. The discussion is not about non-nullable value types.
> * There are two types of reference types:
>   (1) Those that can be initialized on declaration because the coder knows
> what to initialize them to; a.k.a. non-nullable. If the coder does not know
> what to initialize them to at declaration time, then either the design is
> wrong, the coder doesn't understand the algorithm or application, or it is
> truly a complex run-time decision.
>   (2) Those that aren't in set (1); a.k.a. nullable.
> * The standard declaration should imply non-nullable. And if not
> initialized the compiler should complain. This encourages protection, but
> does not guarantee it, of course.
> * To declare a nullable type, use a special syntax to denote that the coder
> is deliberately choosing to declare a nullable reference.
> * The compiler will prevent non-nullable types being simply set to null. As
> D is a system language too, there will be a rare cases that need to subvert
> this compiler protection, so there will need to be a method to explicitly
> set a non-nullable type to a null. The point is that such a method should
> be a visible warning beacon to maintenance coders.
> 
> Priority should be given to coders that prefer safe coding. If a coder, for
> whatever reason, chooses to use nullable references or initialize
> non-nullable reference to rubbish data, then the responsibility is on them
> to ensure safe applications. Safe coding practices should not be penalized.
> 
> The C/C++ programming language is inherently "unsafe" in this regard, and
> that is not news to anyone. The D programming language does not have to
> follow this paradigm.

But it doesn't have to follow the paranoid safety paradigm either. I 
wouldn't like two reference types and casting between the two when 
they're essentially the same with one having a single value that can't 
be set out of 4 billions possibilities. Seems like a waste to me, 
especially since 3 billions of these possibilities will result in the 
same segfault crash than that one you're trying to make illegal on 
nonnull types.

> I'm still not ready to use D for anything, but I watch it in hope.

I'm already using D quite a lot, I don't find null vs nonnull references 
all that meaningful. Like walter said, you can just make your own 
nonnull invariant.

Here's a very, very simple wrapper, took 10 seconds to write:

struct NonNull(C) if(is(C == class)) {
	C ref;
	invariant() { assert(ref !is null); }
	T opDot() { return ref; }
}

C++ has all sort of pointer wrappers like this one, you don't see a 
smart pointer feature in the C++ language for the simple reason its 
widely used and safer. In fact letting the semantics of these pointers 
up to libraries allow any project to write its custom ones, and quite a 
lot do.

It should be the same for D, I believe its better to implement flow 
analysis and let the compiler warn you of uninitialized variables (which 
will solve most nullptr references, the other half being by 
NonNull!Object fields). The compiler could also provide better tools to 
build smart wrapper types upon (like force initialization or prevent 
void initialization, heck even provide a tuple of valid initializers) 
and let libraries write their own.

Jeremie



More information about the Digitalmars-d mailing list