On Monday, 30 January 2017 at 07:33:34 UTC, Ali Çehreli wrote:
As others have said, D's array definition is natural because unlike C's inside-out (or is that outside-in?) syntax, it follows from the alias syntax. Replacing History inside main with Matrix[], etc.:

    History history;    // is the same as:
    Matrix[] history;   // is the same as:
    Row[4][] history;   // is the same as:
    int[4][4][] history;

Ali

Defending array-notation by giving an example of explicitly not using declared aliases makes no sense to me. When I define 2d arrays, or index them, I think in row -> column terms (often math notation for matrix size being; 'rows x columns'), or more generally in big -> small terms, which is clear when using the consistent left->right notation, big picture first followed by detail, honestly the whole concept of encapsulation;

History history;
Matrix[] history;
Row[][4] history; // collection of rows, stored in a dynamic array (top level), each containing 4 (in detail). int[][4][4] history; // collection of integers, stored in a dynamic array (top level), containing 4 rows (->middle level->) of 4 columns (in detail),

Of course, one can also prefer storing in columns, instead of rows, even glsl uses column-major order, just change 'Row' to 'Column' and you're set. My argument here of course rests on outside->in thinking, which one can reverse consistently. I would be fine with that.

At heart however, this declaration design leads to inconsistency.

   int[1][2] history; // 1 columm, 2 rows
vs
   int last_element = history[1][0] // row 1, column 0

This makes no sense to anyone used to reading left to right, or even right to left. Honestly, reversing reading-order when indexing & declaring is the worst idea I could imagine if consistency and readability were your goal. It doesn't make more sense because you're reading 'outward', that would mean I would have to read both left to right _and_ right to left.

The argument Jonathan M Davis gives in this regard hold no water for me.
Like in C/C++, types are mostly read outward from the variable name in D. In both C/C++ and D,

int* foo;

is a pointer to an int. It's read outward from the variable name, so you get the pointer and then what it points to. Similarly,

int** foo;

is a pointer to a pointer to an int.

Feel free to read them the way you want, but personally, I read int* foo as 'integer pointer', which is not 'outward'. Your argument is only based on personal reading preference, but with it you remove indexing consistency & introduce boustrophedon.

You don't even always have the variable name;
... = new int[1][2]
vs
... = new int[][](2, 1)

If you were to ask someone with no prior coding experience how to access a predefined declaration, given a onedimensional explanation, I'm certain they would default to standard western reading order, no matter the presence of a variable name.

I'm surprised this thread is 3 years old by the way, sorry for that, just noticed this is how D handles multidimensional arrays (I may add a note about this to the tour suggestions). It saddens me quite a bit, as I see it as a big design flaw and quite a turn-off, "unfortunately one that can't be fixed" as Profile Analysis put it.

Have a nice & safe christmas!
- Rekel, the disproportionally active forum . . . person (sorry)

Reply via email to