'auto' with AA

David Held via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Apr 28 00:12:55 PDT 2014


On 4/27/2014 9:32 PM, Ali Çehreli wrote:
> fOn 04/27/2014 06:00 PM, David Held wrote:
>
>  > I would like to do something like this:
>  >
>  > Foo[Bar][Baz] nestedAA;
>  > auto innerAA = nestedAA[someBaz];
>  > innerAA[someBar] = someFoo;
>  > assert(someFoo in nestedAA[someBaz]);
>
> in operator uses a key, not a value. This should work:
>
>      assert(someBar in nestedAA[someBaz]);

Sorry, that is what I meant to say.

That is, modifying nestedAA through innerAA does not seem to work, which 
is why I assumed it was a copy.  However, I'm pretty sure that if I use 
auto on an array, I will get a reference:

int[][] matrix = [[1, 2, 3, 4]];
auto array = matrix[0];
array[3] = 42;
assert(matrix[0][3] == 42);

This works just fine.  I assumed that AAs were like arrays, and thus, 
would work like references.  Here is a compilable example which fails:

void main()
{
     double[int][string] nestedAA;
     nestedAA["test"] = null;
     auto innerAA = nestedAA["test"];
     innerAA[42] = 3.14;
     assert(42 in nestedAA["test"]);
}

Note that I can even assign 'null' to the nested AA, which implies to me 
that it's a reference type!  Now, the problem may be that null is 
exactly what gets assigned to innerAA.  But then, why am I able to 
happily index it on the very next line?  And what exactly does it mean 
for an AA to be assigned 'null'?  This is perfectly legal, but I don't 
know what it means:

     double[int] aa = null;

It appears to be a NOP, and indistinguishable from:

     double[int] aa;

In fact, this appears to be the source of the problem.  If I change the 
null assignment above to:

     nestedAA["test"] = [1:1.0];

then everything works as expected, which means that innerAA really is a 
reference.  What is really bizarre is this idea that it starts out as a 
presumed null reference, and becomes instantiated through use.  Note 
that this is inconsistent with arrays:

     double[] a = null;
     a[0] = 3.14;	// Range violation

I suppose the difference is that naming an invalid key in an AA inserts 
the key, but naming an invalid index in an array does not.  What is 
peculiar is that the above is a *range violation* and not an *access 
violation*.  It seems to me that the real problem is that a doesn't 
*refer to an actual array*.  So how can an index into 'a' violate its range?

The problem I have with the AA solution above is that I have to create 
some mapping to "instantiate" the nested AA.  I thought I would be 
clever and create a default initializer, like so:

     nestedAA["test"] = (double[int]).init;

Unfortunately, this appears to be equivalent to assigning null, which I 
assume is the actual value of .init above[1].  Of course, arrays and AAs 
are "magical" types in D, but it is a little frustrating that an empty 
initializer is reduced to the null initializer, even though the empty 
state is not the same as the null state:

     double[int][string] nestedAA;
     nestedAA["test"] = null;
     auto innerAA = nestedAA["test"];
     assert(innerAA.length == 0);	// empty
     assert(innerAA is null);		// null
     innerAA[42] = 3.14;
     assert(innerAA !is null);		// not null
     innerAA.remove(42);
     assert(innerAA.length == 0);	// empty
     assert(innerAA !is null);		// still not null!

If there were an initializer which put the AA in the final state above, 
then I would be happy.  I'm sure that .init == null for performance 
reasons, but I don't see why there isn't some initializer syntax which 
creates a truly empty-but-not-null state, other than that not enough 
people needed it.  I propose something like:

     double[int] aa = [void:void];
     assert(aa.length == 0);
     assert(aa !is null);

Unfortunately, this is exactly backwards.  This *should* be the syntax 
to make a "null" AA, and .init should make the empty one.  But history 
has prevented that solution.  Anything I'm missing?

Dave

[1] Unfortunately, .init is not documented here: 
http://dlang.org/hash-map.html even though it is documented for arrays



More information about the Digitalmars-d-learn mailing list