Empty VS null array?

Jonathan M Davis jmdavisProg at gmx.com
Fri Oct 18 11:04:41 PDT 2013


On Friday, October 18, 2013 10:38:12 H. S. Teoh wrote:
> On Fri, Oct 18, 2013 at 01:32:58PM -0400, Jonathan M Davis wrote:
> > On Friday, October 18, 2013 09:55:46 Andrei Alexandrescu wrote:
> > > On 10/18/13 9:26 AM, Max Samukha wrote:
> > > > *That's* bad API design. readln should be symmetrical to writeln,
> > > > not write. And about preserving the exact representation of new
> > > > lines, readln/writeln shouldn't preserve that, pure and simple.
> > > 
> > > Fair point. I just gave one possible alternative out of many. Thing
> > > is, relying on client code to distinguish subtleties between empty
> > > and null strings is fraught with dangers.
> > 
> > Yeah, but the primary reason that it's bad design is the fact that D
> > tries to conflate null and empty instead of keeping them distinct
> > (which is essentially the complaint that was made). Whether that's
> > ultimately good or bad is up for debate, but the side effect is that
> > relying on the difference between null and empty ends up being very
> > bug-prone, whereas in other languages which don't conflate the two, it
> > isn't problematic in the same way, and it's much more reasonable to
> > have the API treat them differently.
> 
> [...]
> 
> IMO, distinguishing between null and empty arrays is bad abstraction. I
> agree with D's "conflation" of null with empty, actually. Conceptually
> speaking, an array is a sequence of values of non-negative length. An
> array with non-zero length contains at least one element, and is
> therefore non-empty, whereas an array with zero length is empty. Same
> thing goes with a slice. A slice is a view into zero or more array
> elements. A slice with zero length is empty, and a slice with non-zero
> length contains at least one element. There's nowhere in this conceptual
> scheme for such a thing as a "null array" that's distinct from an empty
> array. This distinction only crops up in implementation, and IMO leads
> to code smells because code should be operating based on the conceptual
> behaviour of arrays rather than on the implementation details.

In most languages, an array is a reference type, so there's the question of 
whether it's even _there_. There's a clear distinction between having null 
reference to an array and having a reference to an empty array. This is 
particularly clear in C++ where an array is just a pointer, but it's try in 
plenty of other languages that don't treat as arrays as pointers (e.g. Java).

The problem is that D put the length on the stack alongside the pointer, 
making it so that D arrays are sort of reference types and sort of not. The 
pointer is a reference type, but the length is a value type, making the 
dynamic array half and half. If it were fully a reference type, then there 
would be no problem with distinguishing between null and empty arrays. A null 
array is simply a null reference to an array. But since D arrays aren't quite 
reference types, that doesn't work.

I see no problem in the abstraction of arrays with having null arrays, because 
a null array is simply a null reference to an array, which is exactly the same 
as having a null object or null pointer. It's the reference that's null, not 
what it points to. It's just D's implementation that's weird. It would be like 
taking some of the member variables of a class and putting them in the 
reference instead of in the object and then discussing how much a null object 
makes sense. It's just bizarre.

Now, D arrays end up working great overall in spite of their semantic 
weirdness, but it does mean that you can't really have proper null arrays in 
the same way that most languages with arrays can, forcing you to either be 
extremely careful when dealing with null and arrays or to waste space doing 
stuff to keep track of nullability separately from the array itself like 
Nullable does.

- Jonathan M Davis


More information about the Digitalmars-d mailing list