www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Array Operations and type inference

reply simendsjo <simen.endsjo pandavre.com> writes:
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
	}
	
Aug 07 2010
next sibling parent Mafi <mafi example.org> writes:
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
 }

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.
Aug 07 2010
prev sibling next sibling parent reply Mafi <mafi example.org> writes:
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?
 }

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
 }

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]);
 }

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]);
 }

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?
 }

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]);
 }

 {
 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
 }

Aug 07 2010
parent Don <nospam nospam.com> writes:
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?
 }

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.
Aug 07 2010
prev sibling parent simendsjo <simen.endsjo pandavre.com> writes:
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.
Aug 08 2010