Thread overview
Array Operations and type inference
Aug 07, 2010
simendsjo
Aug 07, 2010
Mafi
Aug 07, 2010
Mafi
Aug 07, 2010
Don
Aug 08, 2010
simendsjo
August 07, 2010
I'm new to D2, so please.. :)

The spec on Array Operations, http://www.digitalmars.com/d/2./arrays.html says:
"""A vector operation is indicated by the slice operator appearing as the lvalue of an =, +=, -=, *=, /=, %=, ^=, &= or |= operator."""

The following tests works fine as I expected:


	{
		double[3] a = [1,1,1];
		double[3] b;
		b[] = a[] + 3;
		assert(a == [1,1,1]);
		assert(b == [4,4,4]);
	}
	
	{
		double[3] a = [1,1,1];
		auto b = a;
		b[] = a[] + 3;
		assert(a == [1,1,1]);
		assert(b == [4,4,4]);
	}

But from here on I'm having problems...

	{
		double[] a = [1,1,1];
		double[] b;
		b[] = a[] + 3;
		assert(a == [1,1,1]);
		assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler say something?
	}
	
	{
		double[] a = [1,1,1];
		double[] b;
		b.length = a.length;
		b[] = a[] + 3;
		assert(a == [1,1,1]);
		assert(b == [4,4,4]); // Now it's fine
	}
	
	{
		double[3] a = [1,1,1];
		double[3] b = a[] + 3; // works although lvalue isn't a slice. Static arrays? Because it's an initial value?
		assert(a == [1,1,1]);
		assert(b == [4,4,4]);
	}
	
	{
		double[3] a = [1,1,1];
		auto b = a;
		b = a[] + 3; // And so does this.. Something to do with static arrays?
		assert(a == [1,1,1]);
		assert(b == [4,4,4]);
	}
	
	{ // Like the previous example, but with dynamic arrays..
		double[] a = [1,1,1];
		auto b = a;
		assert(a is b);
		b = a[] + 3;
		assert(a == [1,1,1]);
		//writeln(b); // access violation. Because of dynamic arrays?
	}	

	{ // Like above, but using slicing like the spec says.. Works fine
		double[] a = [1,1,1];
		auto b = a;
		assert(a is b);
		writeln(typeof(b).stringof); // double[]
		b[] = a[] + 3;
		assert(a == [4,4,4]); // a also changed. I expected this
		assert(b == [4,4,4]);
	}
	
	{
		double[3] a = [1,1,1];
		auto b = a[] + 3; // What happens here?
		writeln(typeof(b).stringof); // double[]
		assert(b.length == 3);
		assert(b.capacity == 0);
		//writeln(b); // access violation
	}
	
	{ // Same as above?
		double[3] a = [1,1,1];
		//writeln(a[] + 3); // access violation
	}
	
August 07, 2010
Am 07.08.2010 14:10, schrieb simendsjo:
> I'm new to D2, so please.. :)
>
> The spec on Array Operations,
> http://www.digitalmars.com/d/2./arrays.html says:
> """A vector operation is indicated by the slice operator appearing as
> the lvalue of an =, +=, -=, *=, /=, %=, ^=, &= or |= operator."""
>
> The following tests works fine as I expected:
>
>
> {
> double[3] a = [1,1,1];
> double[3] b;
> b[] = a[] + 3;
> assert(a == [1,1,1]);
> assert(b == [4,4,4]);
> }
>
> {
> double[3] a = [1,1,1];
> auto b = a;
> b[] = a[] + 3;
> assert(a == [1,1,1]);
> assert(b == [4,4,4]);
> }
>
> But from here on I'm having problems...
>
> {
> double[] a = [1,1,1];
> double[] b;
> b[] = a[] + 3;
> assert(a == [1,1,1]);
> assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler
> say something?
> }
>
> {
> double[] a = [1,1,1];
> double[] b;
> b.length = a.length;
> b[] = a[] + 3;
> assert(a == [1,1,1]);
> assert(b == [4,4,4]); // Now it's fine
> }
>
> {
> double[3] a = [1,1,1];
> double[3] b = a[] + 3; // works although lvalue isn't a slice. Static
> arrays? Because it's an initial value?
> assert(a == [1,1,1]);
> assert(b == [4,4,4]);
> }
>
> {
> double[3] a = [1,1,1];
> auto b = a;
> b = a[] + 3; // And so does this.. Something to do with static arrays?
> assert(a == [1,1,1]);
> assert(b == [4,4,4]);
> }
>
> { // Like the previous example, but with dynamic arrays..
> double[] a = [1,1,1];
> auto b = a;
> assert(a is b);
> b = a[] + 3;
> assert(a == [1,1,1]);
> //writeln(b); // access violation. Because of dynamic arrays?
> }
>
> { // Like above, but using slicing like the spec says.. Works fine
> double[] a = [1,1,1];
> auto b = a;
> assert(a is b);
> writeln(typeof(b).stringof); // double[]
> b[] = a[] + 3;
> assert(a == [4,4,4]); // a also changed. I expected this
> assert(b == [4,4,4]);
> }
>
> {
> double[3] a = [1,1,1];
> auto b = a[] + 3; // What happens here?
> writeln(typeof(b).stringof); // double[]
> assert(b.length == 3);
> assert(b.capacity == 0);
> //writeln(b); // access violation
> }
>
> { // Same as above?
> double[3] a = [1,1,1];
> //writeln(a[] + 3); // access violation
> }
>
Hi,
I don't the answer to all of your problems but what I can say you is:
* D-Arrays are references to structs which point to the data
* An arrayvariable on the left-hand-side of an assignment sets the reference of this variable. (no copy!)
* An array slice is mostly the same as the array variable itself but if it's on the left-hand-side of an assignment, the data is copied from the right-hand-side.

So for example your third example can't work because b is null and so there's no place you can copy the data to.
August 07, 2010
Hey, here Mafi again,
I thought about your snippets and here's what I have.

Am 07.08.2010 14:10, schrieb simendsjo:
> {
> double[3] a = [1,1,1];
> double[3] b;
> b[] = a[] + 3;
> assert(a == [1,1,1]);
> assert(b == [4,4,4]);
> }
>
> {
> double[3] a = [1,1,1];
> auto b = a;
> b[] = a[] + 3;
> assert(a == [1,1,1]);
> assert(b == [4,4,4]);
> }
>
> But from here on I'm having problems...
>
> {
> double[] a = [1,1,1];
> double[] b;
> b[] = a[] + 3;
> assert(a == [1,1,1]);
> assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler say something?
> }
As I said in my first post b is null. Now the third line tries to _copy_ the result to b which is impossible. About your question:
that the compiler complains would be difficult but in my opinion it should result in an runtime error.
>
> {
> double[] a = [1,1,1];
> double[] b;
> b.length = a.length;
> b[] = a[] + 3;
> assert(a == [1,1,1]);
> assert(b == [4,4,4]); // Now it's fine
> }
With setting b's length you (re)allocate(1) memory for the array so now there's place to copy to.

> {
> double[3] a = [1,1,1];
> double[3] b = a[] + 3; // works although lvalue isn't a slice. Static
> arrays? Because it's an initial value?
> assert(a == [1,1,1]);
> assert(b == [4,4,4]);
> }
You simply intialize the fixed-size array with a dynamic one. I'm not sure but I think the data is copied out of the dynamic temporary array to b.
> {
> double[3] a = [1,1,1];
> auto b = a;
> b = a[] + 3; // And so does this.. Something to do with static arrays?
> assert(a == [1,1,1]);
> assert(b == [4,4,4]);
> }
In the second line you initialize to a and then do the same as above.
Note: In D fixed-size arrays are value types.
> { // Like the previous example, but with dynamic arrays..
> double[] a = [1,1,1];
> auto b = a;
> assert(a is b);
> b = a[] + 3;
> assert(a == [1,1,1]);
> //writeln(b); // access violation. Because of dynamic arrays?
> }
I have no idea. Maybe the array generated by the vector addition is kind of temporary and you have to copy. But it could also be a bug.
Vector-operations are still quite buggy.
> { // Like above, but using slicing like the spec says.. Works fine
> double[] a = [1,1,1];
> auto b = a;
> assert(a is b);
> writeln(typeof(b).stringof); // double[]
> b[] = a[] + 3;
> assert(a == [4,4,4]); // a also changed. I expected this
> assert(b == [4,4,4]);
> }
Now you are copying to b(which references the same struct as a).
> {
> double[3] a = [1,1,1];
> auto b = a[] + 3; // What happens here?
> writeln(typeof(b).stringof); // double[]
> assert(b.length == 3);
> assert(b.capacity == 0);
> //writeln(b); // access violation
> }
It's the same as to steps before this(my  english isn't ver good ;))
> { // Same as above?
I think it is.
> double[3] a = [1,1,1];
> //writeln(a[] + 3); // access violation
> }
>
(1)It's normally for reallocation when you need more space.

August 07, 2010
Mafi wrote:
> Hey, here Mafi again,
> I thought about your snippets and here's what I have.
> 
> Am 07.08.2010 14:10, schrieb simendsjo:

>> { // Like the previous example, but with dynamic arrays..
>> double[] a = [1,1,1];
>> auto b = a;
>> assert(a is b);
>> b = a[] + 3;
>> assert(a == [1,1,1]);
>> //writeln(b); // access violation. Because of dynamic arrays?
>> }
> I have no idea. Maybe the array generated by the vector addition is kind of temporary and you have to copy. But it could also be a bug.
> Vector-operations are still quite buggy.

That is bug 4578, which has been fixed, and will be in the next compiler release.
August 08, 2010
On 07.08.2010 14:10, simendsjo wrote:
> I'm new to D2, so please.. :)
>
(...)

Thanks for all answers. Seems array operations is a bit buggy, so I'll rather look more into them at a later date.