Changeset 442, implicit Vs explicit

bearophile bearophileHUGS at lycos.com
Tue Apr 27 04:37:01 PDT 2010


Do you see a problem here?

import std.stdio: writeln;
int[24] arr = [10,2,15,15,14,12,3,7,13,5,9,9,7,9,9,9,11,15,1,1,12,5,14];
void main() {
    writeln(arr);
}

This code compiles and runs fine, I think according to the D specs, but it can hide a bug.

There are three main situations where you use an array literal to define a fixed-size array:
1) You want a static array that contains as many items as in the literal. This is a common case, maybe the most common in my code. For this I and other people have suggested a simple syntax that helps avoid to count the items:
int[$] arr = [10,2,15,15,14,12,3,7,13,5,9,9,7,9,9,9,11,15,1,1,12,5,14];
2) You want an array with N items. In this situation you put N in the type definition, on the left as in that 'arr' array. This situation can lead to bugs in D code because the compiler accepts literals with a length different from N. Changeset 442 fixes part of this situation but I don't know if it fixes the whole problem (because it'a a big changeset and I don't understand all the things it changes).
(Don has split my bug report to avoid fixing the whole problem. I don't think mine is an enhancement request as Don writes, I think it's a bug in the D specs.)

The changeset 442:
http://dsource.org/projects/dmd/changeset/442

It's relative to this bug reported by Don:
http://d.puremagic.com/issues/show_bug.cgi?id=3974

That comes from this bug report of mine:
http://d.puremagic.com/issues/show_bug.cgi?id=3849

My opinion is that those two cases cover most situations. So I think it's positive to raise errors if the literal has less items than the specified N, because that 'arr' literal is likely a bug, it defines trailing zeros in an implicit way. As the second item in the Python Zen says: "Explicit is better than implicit.". I desire to avoid sources of bugs in D, when possible because a programmer wants to give all his/her/hir attention to the more serious sources of bugs, like data corruption, database mistakes, etc, instead of error-prone minutiae of the language syntax.

A third case is when you really want to define a static array using a literal that has less items than the static array. I think this is an uncommon case, what are the real use cases of this? But we might want to support it anyway. Two examples:

int[4] datas = [1, 2];
int[3][3] mat = [[1,2,3], [4,5,6]];

In D there is another way to write that (using the associative array syntax! this smells bad):
int[4] datas = [0:1, 1:2];

Another possibile syntax not currently supported, that I don't like:
int[4] datas = [1, 2,,];

A better and explicit syntax, that uses the * array operator as in Python (this mul and concat operations are done at compile-time):
int[4] datas = [1, 2] ~ ([0] * 2);

Or even, using Phobos (this concat operation has to be done at compile-time):
int[4] datas = [1, 2] ~ StaticArr!(2);

Another:
@implicit_filling int[4] datas = [1, 2];
Or:
@implicit_array_filling int[4] datas = [1, 2];

If you have other ideas you can show them.
In practice many things are better than nothing, that is than a silent implicit initialization.

Bye,
bearophile



More information about the Digitalmars-d mailing list