Empty array literals

bearophile bearophileHUGS at lycos.com
Sat Mar 6 18:30:35 PST 2010


First part:

I prefer a language that uses literals that are as much as possible clear, readable and unambiguous. In D "null" can represent empty pointers, empty class references, and empty dynamic arrays:


int[] foo(int[] a) {
    return null;
}
int[] foo2(int[] a) {
    return [];
}
void main() {
    foo(cast(int[])null);
    foo(null);
    foo([]);
    foo2(cast(int[])null);
    foo2(null);
    foo2([]);
}


But "null" is not a clear way to represent an empty array, that is a struct of two items (this reminds me of the untidy usage of 0 to represent a null pointer in C). So I propose to remove/deprecate the usage of "null" to represent an empty dynamic array (the Delight D-derived language already allows only [] for such purpose).


Note: [] is not fully unambiguous, it doesn't specify a type. Specifying a type can be useful, because you can use it to give as argument to a template function an array of the correct type:


import std.stdio: writeln;
void foo(T)(T[] a) {
    writeln(typeid(T));
}
void main() {
    // OK, int[]
    foo(cast(int[])null);

    // OK, int[]
    foo(cast(int[])[]);

    // Partially OK, inside foo 'a' is of type void[]
    foo([]);

    // Bad, Error: template test.foo(T) does not match any function template declaration
    foo(null);
}


In such situations cast(int[])[] is enough. I think this idiom isn't common in D code.

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

Second part (this is less nice than the first part):

In D null can also be used to represent an empty associative array. If you think of AAs as instances of a class to be used by reference, then using a null to represent an empty AA is meaningful (the main difference is that you don't need "new" to allocate it at the beginning).

But I think currently associative arrays are not instances of a normal class, so this is a fourth different overload of the meaning of "null". To remove some semantic overload, the empty untyped associative array can be represented with a different literal, for example like:

[:]

Where needed, for templates, you can use that literal with types too, as in the dynamic array case:

cast(int[float])[:]

If in future associative arrays will become true instances of a templated class, then it's better to restore the usage of 'null'.


If you think there is something good in what I have written, then later I am willing to create a bug report from the first part (or both parts) of this post.

Bye,
bearophile



More information about the Digitalmars-d mailing list