View mode: basic / threaded / horizontal-split · Log in · Help
December 20, 2011
initializedArray
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?
December 20, 2011
Re: initializedArray
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?
December 20, 2011
Re: initializedArray
I would go even further, and give a *function* as an argument - 
function that will be used to initialise values.
December 20, 2011
Re: initializedArray
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
December 20, 2011
Re: initializedArray
*Also those two templates can be merged, I just have to change the constraints.
December 20, 2011
Re: initializedArray
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 :-)
December 20, 2011
Re: initializedArray
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. :)
December 21, 2011
Re: initializedArray
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)
December 21, 2011
Re: initializedArray
On 12/21/11, Philippe Sigaud <philippe.sigaud@gmail.com> wrote:
> size_t[] arrayLengths(A)(A a) if (isStaticArray!A)
> {
>     static if (isStaticArray!(ElementType!A))
> 	return arrayLengths(a[0]) ~  a.length;
>     else
>         return [a.length];
> }

That returns an array, but I can't pass an array in place of a
variadic argument.

The prototype of uninitializedArray is:
auto uninitializedArray(T, I...)(I sizes)
if(allSatisfy!(isIntegral, I)) { }
December 21, 2011
Re: initializedArray
Ok just realized I can't use a mixin, lengths are dynamic, heheh. That
went over my head. I'll see what else I can do..

On 12/21/11, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> On 12/21/11, Philippe Sigaud <philippe.sigaud@gmail.com> wrote:
>> size_t[] arrayLengths(A)(A a) if (isStaticArray!A)
>> {
>>     static if (isStaticArray!(ElementType!A))
>> 	return arrayLengths(a[0]) ~  a.length;
>>     else
>>         return [a.length];
>> }
>
> That returns an array, but I can't pass an array in place of a
> variadic argument.
>
> The prototype of uninitializedArray is:
> auto uninitializedArray(T, I...)(I sizes)
> if(allSatisfy!(isIntegral, I)) { }
>
Top | Discussion index | About this forum | D home