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

bearophile bearophileHUGS at lycos.com
Wed Jul 3 07:33:01 PDT 2013


Time ago I have opened an enhancement request for empty 
associative array literals:

http://d.puremagic.com/issues/show_bug.cgi?id=7227

This is currently correct code:

void foo(int[int] bb) {}
void main() {
     int[int] aa;
     aa = null;
     foo(null);
     int[int][] aas = [null, null];
}


With the proposal it becomes:

void foo(int[int] bb) {}
void main() {
     int[int] aa;
     aa = [:];
     foo([:]);
     int[int][] aas = [[:], [:]];
}


I am writing about it here because Henning Pohl has written a 
first version of a patch:

https://github.com/D-Programming-Language/dmd/pull/2284

- - - - - - - - - - - - -

The patch by Henning Pohl uses the [] syntax as literal for empty 
associative array, but I prefer the [:] syntax, because it's more 
precise.

Kenji Hara shows the ambiguity of the [] syntax (that was already 
present with using "null" as literals), that [:] lacks:

void foo(int[]);
void foo(int[int]);
foo([]);   // prefer int[] overload, or ambiguous?

- - - - - - - - - - - - -

On GitHub yebblies commented:

> Ideally this would not be the same as K[V] aa = null;,
> it would behave like K[V] aa = new K[V]; - an AA would be 
> allocated.

I think this is a bad idea, because then the semantics of D code 
changes if you use [:] instead of null. D associative arrays have 
problems:


void test(int[int] arraya, int x) {
     arraya[x] = x;
}

void main() {
     int[int] d;
     test(d, 0);
     int[int] d0;
     assert(d == d0); // d is empty, 0:0 is lost

     d[1] = 1;
     test(d, 2);
     assert(d == [1: 1, 2: 2]); // now 2:2 is not lost
}


Compared to the output of this Python code:

def test(arraya, x):
     arraya[x] = x

def main():
     d = {}
     test(d, 0)
     assert d == {0: 0}

     d[1] = 1
     test(d, 2)
     assert d == {0: 0, 1: 1, 2: 2}
main()


Such problems should be faced in other ways. Making the 
associative array literal semantics even more complex is not 
helping.

This problem is present for dynamic arrays too, and I asked to 
fix it:

http://d.puremagic.com/issues/show_bug.cgi?id=5788

- - - - - - - - - - - - -

With the introduction of the new empty associative array literal 
it's a good idea to warn against the usage of the older "null" 
literal:

void foo(int[int]) {}
void main() {
     foo(null);
     int[int][] aas = [null];
     aas[0] = [1: 2, 2: 3];
}


Should give the warnings:

test.d(3): Warning: explicit [:] empty associative array literal 
is better than null, that will be deprecated
test.d(4): Warning: explicit [:] empty associative array literal 
is better than null, that will be deprecated


The wording of such warning message is modelled on another 
warning message:

test.d(3): Warning: explicit element-wise assignment (a)[] = 2 is 
better than a = 2


For Jonathan M Davis: this is a new warning, but later it's 
supposed to become a deprecation message, and then an error. So 
this is not meant meant to be a permanent warning.

Lot of time ago I have also proposed to deprecate "null" as 
literal for dynamic arrays, this goes well with the idea that 
dynamic arrays are not pointers (the * syntax was disallowed for 
dynamic arrays, etc), this is meant to go with the optimization 
requested in issue 5788:

http://d.puremagic.com/issues/show_bug.cgi?id=3889

Bye,
bearophile


More information about the Digitalmars-d mailing list