I think it would be cool to have an initializedArray function, which creates and initializes an array with a *specific* initializer. A hardcoded example would be:
import std.array;
auto initializedArray(F:float[])(size_t size, float init)
{
auto arr = uninitializedArray!(float[])(size);
arr[] = init;
return arr;
}
void main()
{
float[] arr = initializedArray!(float[])(3, 0.0f);
assert(arr[] == [0.0f, 0.0f, 0.0f]);
}
Currently there's no D syntax for using new on arrays and specifying a specific initializer, so maybe we should have this as a library function. Thoughts?

I think this is a great idea and a good example of adding to the library rather than changing the syntax.
Paul
"Wouldn't the sentence 'I want to put a hyphen between the words Fish and And and And and Chips in my Fish-And-Chips sign' have been clearer if quotation marks had been placed before Fish, and between Fish and and, and and and And, and And and and, and and and And, and And and and, and and and Chips, as well as after Chips?" — Martin Gardner
On Tuesday, 20 December 2011 at 12:55:18 UTC, Andrej Mitrovic wrote:
> I think it would be cool to have an initializedArray function, which
> creates and initializes an array with a *specific* initializer. A
> hardcoded example would be:
>> import std.array;
>> auto initializedArray(F:float[])(size_t size, float init)
> {
> auto arr = uninitializedArray!(float[])(size);> arr[] = init;
> return arr;
> }
>> void main()
> {
> float[] arr = initializedArray!(float[])(3, 0.0f);
> assert(arr[] == [0.0f, 0.0f, 0.0f]);
> }
>> Currently there's no D syntax for using new on arrays and specifying a
> specific initializer, so maybe we should have this as a library
> function. Thoughts?

On 12/20/11, Dejan Lekic <dejan.lekic@gmail.com> wrote:
> I would go even further, and give a *function* as an argument - function that will be used to initialise values.
Well I don't know about functions yet, but I did need to use another array as an initializer. So the new implementation takes care of that via lockstep:
http://www.ideone.com/gKFTK

On Tue, Dec 20, 2011 at 21:20, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> On 12/20/11, Dejan Lekic <dejan.lekic@gmail.com> wrote:
>> I would go even further, and give a *function* as an argument - function that will be used to initialise values.
>> Well I don't know about functions yet, but I did need to use another array as an initializer. So the new implementation takes care of that via lockstep:
from : http://www.ideone.com/gKFTK :
unittest
{
auto arr2 = initializedArray!(int[][])([[1, 2], [3, 4]], 2, 2);
assert(arr2 == [[1, 2], [3, 4]]);
}
1) What's the difference with using auto arr2 == [[1,2],[3,4]].dup; ?
(I honestly asks, I don't know much about D's assignements)
2) You can get the lengths of [[1,2],[3,4]], so the 2,2 args is redundant. What happens if you type:
auto arr2 = initializedArray!(int[][])([[1, 2], [3, 4]], 4, 10);
3) I still think you should relax the constraint on the init value's type. You do not need it to be *exactly* BaseElementType!T. Thats stops you from writing
auto arr2 = initializedArray!(float[][])(3, 2,3);
4-ish) No need to attribute the rank/BaseElementType code to me :-)

On 12/20/11, Philippe Sigaud <philippe.sigaud@gmail.com> wrote:
> 1) What's the difference with using auto arr2 == [[1,2],[3,4]].dup; ?
> (I honestly asks, I don't know much about D's assignements)
dup is not a deep copy, it only copies the first elements. The first elements are two slices, so:
void main()
{
auto a = [[1, 2], [3, 4]];
auto b = a.dup;
a[0][0] = 10;
assert(b[] == [[1, 2], [3, 4]]); // fails, b[0][0] is 10
}
> 2) You can get the lengths of [[1,2],[3,4]], so the 2,2 args is redundant. What happens if you type:
>> auto arr2 = initializedArray!(int[][])([[1, 2], [3, 4]], 4, 10);
Right, it's broken to say the least. That's what I get for a 10 second implementation.. Btw, uninitializedArray takes variadic arguments, how would I get the lengths of the dimensions as a tuple that can be passed in place of the variadic argument? I.e.:
auto dupArray(int[][] src) // say src is int[1][2]
{
auto arr = uninitializedArray!(int[][])( /* need 1, 2 here */ );
// ..then copy each element..
}
I could use a mixin, but there should be an easier way to do this? You're good with templates so I'm asking you! :)
> 3) I still think you should relax the constraint on the init value's type. You do not need it to be *exactly* BaseElementType!T. Thats stops you from writing
>> auto arr2 = initializedArray!(float[][])(3, 2,3);
I often fall to this trap. I think there's a syntax for checking if a type is implicitly convertible to another type? I haven't read your book fully yet, btw.
> 4-ish) No need to attribute the rank/BaseElementType code to me :-)
>
I say the same thing for when people use my code, but usually it's best not to assume ownership. :)

On Tue, Dec 20, 2011 at 23:42, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> On 12/20/11, Philippe Sigaud <philippe.sigaud@gmail.com> wrote:
>> 1) What's the difference with using auto arr2 == [[1,2],[3,4]].dup; ?
>> (I honestly asks, I don't know much about D's assignements)
>> dup is not a deep copy, it only copies the first elements. The first elements are two slices
Ah OK. Where as your version does a deep dupping, I see.
>> 2) You can get the lengths of [[1,2],[3,4]], so the 2,2 args is redundant. What happens if you type:
>>>> auto arr2 = initializedArray!(int[][])([[1, 2], [3, 4]], 4, 10);
>> Right, it's broken to say the least. That's what I get for a 10 second implementation..
I tend to do that also :)
> Btw, uninitializedArray takes variadic arguments, how
> would I get the lengths of the dimensions as a tuple that can be
> passed in place of the variadic argument? I.e.:
>> auto dupArray(int[][] src) // say src is int[1][2]
> {
> auto arr = uninitializedArray!(int[][])( /* need 1, 2 here */ );
>> // ..then copy each element..
> }
Having thought a bit more about this, there is a difference between static and dynamic arrays. For static arrays, the length is part of the type, so getting them should be straightforward.
Untested:
size_t[] arrayLengths(A)(A a) if (isStaticArray!A)
{
static if (isStaticArray!(ElementType!A))
return arrayLengths(a[0]) ~ a.length;
else
return [a.length];
}
But for dynamic arrays, int[][] can be a jagged (non square) array. And now that array literal are dynamic, the only way I see would be to collect the max length for all dimensions.
[[1,2,3],
[4,5]] -> 2 rows, 3 columns.
>> 3) I still think you should relax the constraint on the init value's type. You do not need it to be *exactly* BaseElementType!T. Thats stops you from writing
>>>> auto arr2 = initializedArray!(float[][])(3, 2,3);
>> I often fall to this trap. I think there's a syntax for checking if a type is implicitly convertible to another type?
There is 'is(A : B)', but when I tried this with your code, it didn't
work (maybe I was confused between double and floats). That's why I
used std.traits.isImplicitlyConvertible!(From,To)