Thread overview
Multi-dimensional fixed arrays
Jun 30, 2015
DLearner
Jun 30, 2015
Justin Whear
Jun 30, 2015
jmh530
Jun 30, 2015
DLearner
Jun 30, 2015
jmh530
Jun 30, 2015
Justin Whear
Jul 01, 2015
DLearner
Jun 30, 2015
vladde
Jun 30, 2015
vladde
June 30, 2015
Suppose:
'int [1][2] foo;'

Probably I misunderstand, but TDPL seems to say that foo has two elements:
foo[0][0] and foo[1][0]

as opposed to two elements:
foo[0][0] and foo[0][1]

Is this correct?
June 30, 2015
On Tue, 30 Jun 2015 20:09:50 +0000, DLearner wrote:

> Suppose:
> 'int [1][2] foo;'
> 
> Probably I misunderstand, but TDPL seems to say that foo has two
> elements:
> foo[0][0] and foo[1][0]
> 
> as opposed to two elements:
> foo[0][0] and foo[0][1]
> 
> Is this correct?

No.  The order of braces when indexing is the opposite of the order when
declaring.
The declaration
> int [1][2] foo;
reads innermost to outermost, "((int [1] ) [2])"

When indexing foo, you index from outermost to innermost, so
> foo[1]
means the second one-element array and
> foo[1][0]
means the first element of the second one-element array.
June 30, 2015
I am pretty surprised, as the following code gives errors.

>void main(){
>    int [1][2] foo;
>
>    foo[0][0] = 1;
>    foo[0][1] = 2;
>    foo[1][0] = 3;
>    foo[1][1] = 4;
>}

Those errors are:
>app.d(5): Error: array index 1 is out of bounds foo[0][0 .. 1]
>app.d(7): Error: array index 1 is out of bounds foo[1][0 .. 1]

Could anyone more experienced than me explain why this is, and why not it's "the other way around"?
June 30, 2015
Oh, seems I should learn to refresh the page :)
June 30, 2015
On Tuesday, 30 June 2015 at 20:17:12 UTC, Justin Whear wrote:
> No.  The order of braces when indexing is the opposite of the order when
> declaring.
> The declaration
>> int [1][2] foo;
> reads innermost to outermost, "((int [1] ) [2])"
>
> When indexing foo, you index from outermost to innermost, so
>> foo[1]
> means the second one-element array and
>> foo[1][0]
> means the first element of the second one-element array.

I think this is a good explanation.

Looking through
http://dlang.org/arrays.html
I see that the multidimensional array indexing is not particularly focused on (could be improved?). I tend to prefer reasoning things through than relying on a rule (more likely to forget the rule). Thus, I would recommend the OP looks at the way they describe the prefix array declarations for multidimensional arrays. They have the example
int[4][3] b;  // array of 3 arrays of 4 ints each
So you can think of b as an array containing 3 arrays with 4 ints each. For the OP's foo, he should think of foo as an array containing 2 arrays with 1 int each. Moreover, it's more likely that you want to index the arrays and then what's in the arrays, i.e. it's more likely that you would want to do something with the first array of foo and then the second array of foo. This notation makes it a little bit easier to do that.
June 30, 2015
On Tuesday, 30 June 2015 at 20:33:31 UTC, jmh530 wrote:
> On Tuesday, 30 June 2015 at 20:17:12 UTC, Justin Whear wrote:
>> [...]
>
> I think this is a good explanation.
>
> Looking through
> http://dlang.org/arrays.html
> I see that the multidimensional array indexing is not particularly focused on (could be improved?). I tend to prefer reasoning things through than relying on a rule (more likely to forget the rule). Thus, I would recommend the OP looks at the way they describe the prefix array declarations for multidimensional arrays. They have the example
> int[4][3] b;  // array of 3 arrays of 4 ints each
> So you can think of b as an array containing 3 arrays with 4 ints each. For the OP's foo, he should think of foo as an array containing 2 arrays with 1 int each. Moreover, it's more likely that you want to index the arrays and then what's in the arrays, i.e. it's more likely that you would want to do something with the first array of foo and then the second array of foo. This notation makes it a little bit easier to do that.

Out of curiosity, why can't D define a 2-dim array by something like:
int(2,1) foo;

which defines two elements referred to as:
foo(0,0) and foo(1,0)?

It just seems unnatural (if not actually dangerous) to me
to have the array index order reverse between definition and use.
June 30, 2015
On Tuesday, 30 June 2015 at 21:02:39 UTC, DLearner wrote:
> On Tuesday, 30 June 2015 at 20:33:31 UTC, jmh530 wrote:
>> On Tuesday, 30 June 2015 at 20:17:12 UTC, Justin Whear wrote:
>>> [...]
>>
>> I think this is a good explanation.
>>
>> Looking through
>> http://dlang.org/arrays.html
>> I see that the multidimensional array indexing is not particularly focused on (could be improved?). I tend to prefer reasoning things through than relying on a rule (more likely to forget the rule). Thus, I would recommend the OP looks at the way they describe the prefix array declarations for multidimensional arrays. They have the example
>> int[4][3] b;  // array of 3 arrays of 4 ints each
>> So you can think of b as an array containing 3 arrays with 4 ints each. For the OP's foo, he should think of foo as an array containing 2 arrays with 1 int each. Moreover, it's more likely that you want to index the arrays and then what's in the arrays, i.e. it's more likely that you would want to do something with the first array of foo and then the second array of foo. This notation makes it a little bit easier to do that.
>
> Out of curiosity, why can't D define a 2-dim array by something like:
> int(2,1) foo;
>
> which defines two elements referred to as:
> foo(0,0) and foo(1,0)?
>
> It just seems unnatural (if not actually dangerous) to me
> to have the array index order reverse between definition and use.

The notation comes from C. While I think there are many things that could be improved wrt arrays, I'm not sure this is one (in that exact way). However, improved ways to access multidimensional arrays is important to me. There is some work on improved multidimensional array support that may allow access that way I think.
June 30, 2015
On Tue, 30 Jun 2015 21:02:37 +0000, DLearner wrote:

> Out of curiosity, why can't D define a 2-dim array by something like:
> int(2,1) foo;
> 
> which defines two elements referred to as:
> foo(0,0) and foo(1,0)?
Work is being done on multidimensional slicing, see this thread: http://forum.dlang.org/post/dyvzmjfcjzoxvitwbylf@forum.dlang.org
> 
> It just seems unnatural (if not actually dangerous) to me to have the array index order reverse between definition and use.

Think about it this way:

alias IntList = int[10];
IntList[3] myIntLists;
int[10][3] myOtherIntLists; // same type as above

You build the type up from the innermost layer to the outermost and when you access the data you reverse that operation, slicing deeper and deeper.
July 01, 2015
On Tuesday, 30 June 2015 at 22:04:24 UTC, Justin Whear wrote:
>>>
> alias IntList = int[10];
> IntList[3] myIntLists;
> int[10][3] myOtherIntLists; // same type as above
<<<
I understand the rationale, but some issues:

1.  The rationale implicitly takes treats an n-dim array as a (n-1)-dim array x (1)-dim array.

Are we sure this is correct: FWIW, I think an n-dim array is just a set of n-tuple indexes each mapping 1-1 to array elements.
And no more structure than that.

So, although the order of the indexes is important (otherwise we find the wrong element), no subset of tuples (perhaps generated by holding one or more indexes constant) is more important than any other.

2. I _thought_  it was design goal of D that a valid C program, if it compiles under D at all, produces the same output.

That cannot be true if array index order altered.

3. Obscurity: Someone faced with the array definition 'int[a][b] foo;'
is going to instinctively think that the instruction 'bar = foo[x][y];'
means that, potentially, 0 <= x < a and 0<= y < b.
(Which is why if the current design is fixed, I suggested using () instead of [] as an alternate which does match access order to definition order)

Though, in the case of 3., (and really a different question),
there is case for a compiler option making valid range 1 <= x <= a and 1<= y <= b,
as off-by-one error is commonplace bug in C.