Dynamic array creation with default

foobar foo at bar.com
Tue Aug 23 00:40:59 PDT 2011


== Quote from bearophile (bearophileHUGS at lycos.com)'s article
> To create a nD dynamic array and initialize it to a constant value (different
from the init) you currently do something like this:
> auto mat = new bool[][](10, 20);
> foreach (ref row; mat)
>     row[] = true;
> Currently this D code initializes the matrix items to bool.init (false), and
then initializes it all again with true. You sometimes forget to use the "ref",
and they are three lines of code for a single operation.
> Time ago I have seen this as a way to simplify the code, similar to the syntax
for fixed-sized arrays (but Andrei says this is not good):
> auto mat = new bool[][](10, 20) = true;
> This is how you do it in F# (Ada, Python and CommonLisp have different syntax to
do the same thing):
> let mat = Array2D.create 10 20 true
> This has suggested me to add one optional initialization value in D too:
> auto mat = new bool[][](10, 20, true);
> It's a bit more bug-prone, because you sometimes forget a [] and you write:
> auto mat = new int[](10, 20);
> Instead of:
> auto mat = new int[][](10, 20);
> And instead of a matrix you get a 1D array initialized to some integer value.
But I think it's not a big problem.
> A bigger problem is that currently this code is accepted, so you can't use an
optional initialization value:
> auto a = new int[][](5);
> A solution is to always require as many sizes as dimensions, so you have to write:
> auto a = new int[][](5, 0); // OK, no default
> auto a = new int[][](5, 0, 30); // 30 is the default
> Another solution is to introduce named arguments and always require the argument
name for the default value, when you add a default value:
> auto mat = new bool[][](10, 20, default=true);
> Using both solutions at the same time is possible.
> In theory this syntax is also useful to initialize the array to something not
constant, using a delegate (in this universe when uniform has a single input, it
acts like iota(n)), this is a typical use case:
> auto mat10 = new int[][](10, 20, default={ return uniform(9); });
> This replaces a function table() that I have suggested for Phobos.
> Bye,
> bearophile

you raise a valid concern but this looks too complicated.
I'd suggest to simplify into only two cases.

// 1) T.INIT - as you suggested the dimension should be checked
auto foo = new int[][](10, 20); // correct
auto foo1 = new int[][](10); // compilation error

// 2) function of the array dimension
auto bar = new int[][](10, 20, (int x, int y) { return x*y; } );

// if you want a default value just use:
auto bar1 = new int[][](10, 20, { return 3; } );

For fixed-sized arrays the function would be CTFE-able.


More information about the Digitalmars-d mailing list