[:] as empty associative array literal, plus warning for null

Regan Heath reganmheath at gmail.com
Fri Jul 5 15:17:46 PDT 2013


On Friday, 5 July 2013 at 16:22:12 UTC, Andrei Alexandrescu wrote:
> On 7/5/13 2:05 AM, Regan Heath wrote:
>> Why? Because if it were null it would have a different 
>> meaning. It would
>> mean that the comment field was not present on the page at 
>> all, and
>> should not be altered.
>
> I find the example tenuous. Even assuming it has merit, it does 
> not explain the need for a syntactic _literal_ to fulfill that 
> need.

TBH my main concern is the stability of the null/empty states of 
arrays, not the literal.  But, I think the current means by which 
you can create empty arrays, without slicing them from an 
existing array or variable is hackish at best.

Imagine we have a function which accepts an optional array.  
Passing null means, not specified/do nothing, passing non-null 
means assign/use the value.

If we have an existing array or even a local variable of the 
right type we can slice off it to pass empty, but otherwise we're 
screwed .. right?

i.e. How can you call 'foo' below from 'bar' passing an empty 
array for a, b, or c in a generic manner?

import std.stdio;

void foo(T,U,V)(T[] a, U[] b, V[] c)
{
   writefln("a !is null = %s", (a !is null));
   writefln("a.length is = %s", a.length);
   writefln("b !is null = %s", (b !is null));
   writefln("b.length is = %s", b.length);
   writefln("c !is null = %s", (c !is null));
   writefln("c.length is = %s", c.length);
}

void bar(T,U,V)()
{
   V[] c1 = null;
   V[] c2 = new V[0];

   foo!(T,U,V)([], // null, length = 0
     null,         // null, length = 0
     c1);          // null, length = 0
	
   writefln("");

   U i;

   foo!(T,U,V)(cast(T[])"", // !null, length = 0
     cast(U[])(&i)[0..0],   // !null, length = 0
     c2);                   // *null* length = 5
}

void main()
{
   bar!(dchar,int,bool)();
}

The dchar[] works because I cheated/knew the type, the int[] 
requires a local variable to slice off, the bool[] is a local 
array which in the 2nd case is still null!

Is there a better way to do it?

>> There are many such examples.
>
> I am not convinced there are many such examples. I'd call it 
> poor design to make it a cornerstone to distinguish between 
> empty arrays that are null and empty arrays that are not only 
> non-null, but aren't part of any other array!

To be clear I want to be able to distinguish between 
not-specified and specified.  In the specified case I can tell 
empty/not empty by using length.

This may seem like splitting hairs but from my point of view 
there is no such thing as "empty arrays that are null".  If the 
array/slice/parameter "is null" then it is not-specified, or 
non-existent, not empty.  For example if you start with a set of 
2 items, take 2 items away and you have an empty set, take the 
set itself away and you have no set at all 
(non-existent/not-specified).

> Let me emphasize the last part. Ironically, there is a 
> potential interesting use of empty non-null arrays as anchors: 
> an empty slice referring to the interior of an array may be 
> combined with another slice, pointer, or length, to create a 
> new, meaningful slice. However, the discussed literal does 
> nothing of that kind - it just fabricates a slice of an array 
> that does not exist.

Thus allowing us to pass a set which exists but contains no items.

>> All of them can be worked around by
>> various means but these are all more complex and require 
>> additional
>> containers or variables to represent state.
>
> I would say those are better designs.

How exactly?  They're all more complex and/or indirect.  Having a 
single variable which can reflect the intent directly and without 
relying on external state is surely "better".

>> null - does not exist, was not specified.
>> empty - exists and was intentionally set to be empty.
>
> Such empty arrays occur as natural reductions from other 
> arrays. Why yet another literal for such?

Yet another literal?  What other literal are we talking about?  
What if you don't have another array or variable to slice off?

>> I think arrays will be most useful if we can treat them like 
>> safe
>> reference types - this wrappers around the unsafe ptr 
>> reference type. To
>> do that, we need null/empty to be stable/reliable states.
>>
>> If not, then array becomes like 'int' and we have to invent a 
>> special
>> value to represent the null case (or use other 
>> containers/variables to
>> represent null) like we do for int.
>
> I am not convinced.

Fair enough.

It just seems .. annoying to me that I cannot do with a char[] 
array what I can do with a char* pointer (represent 
non-specified, empty, not empty).  That, plus the fact that the D 
array/slice behaviour is not reliable, or consistent, makes it 
seem like a rough edge.


More information about the Digitalmars-d mailing list