Re: What is the difference between a[x][y] and a[x,y]?

2020-01-08 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Jan 08, 2020 at 09:09:23AM +0100, Robert M. Münch via 
Digitalmars-d-learn wrote:
> On 2020-01-07 19:06:09 +, H. S. Teoh said:
> 
> > It's up to you how to implement all of this, of course. The language
> > itself doesn't ship a built-in type that implements this, but it
> > does provide the scaffolding for you to build a custom
> > multi-dimensional array type.
> 
> Hi, thanks for your extensive answer! Helped a lot...
> 
> And the above paraghraph brings it to the core.
> 
> How can this be added to the D docs? I think adding such clear "this
> is the idea how you should use it" intros would help a lot to see the
> world from a d-ish perspective.
[...]

File a bug against dlang.org, and maybe when I get some free time I'll
try to write something up.


T

-- 
Designer clothes: how to cover less by paying more.


Re: What is the difference between a[x][y] and a[x,y]?

2020-01-08 Thread Robert M. Münch via Digitalmars-d-learn

On 2020-01-07 19:06:09 +, H. S. Teoh said:


It's up to you how to implement all of this, of course. The language
itself doesn't ship a built-in type that implements this, but it does
provide the scaffolding for you to build a custom multi-dimensional
array type.


Hi, thanks for your extensive answer! Helped a lot...

And the above paraghraph brings it to the core.

How can this be added to the D docs? I think adding such clear "this is 
the idea how you should use it" intros would help a lot to see the 
world from a d-ish perspective.


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: What is the difference between a[x][y] and a[x,y]?

2020-01-07 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Jan 07, 2020 at 06:38:59PM +0100, Robert M. Münch via 
Digitalmars-d-learn wrote:
> I read all the docs but I'm not toally sure. Is it that [x][y] is a 2D
> array-index, where as [x,y] is a slice?

arr[x][y] is indexing an array of arrays.
arr[x,y] is indexing an actual multi-dimensional array.

The language does not have a built-in implementation of
multi-dimensional arrays, so the only time you can use the arr[x,y]
syntax is when you write your own type that overloads opIndex.

Here's a quick-n-dirty example:

struct Array2D(T) {
private T[] impl;
private int width, height;

this(int w, int h) {
width = w;
height = h;
impl.length = width*height;
}

// Notice that opIndex takes *two* parameters, this is
// what allows us to use arr[x,y] syntax.
ref T opIndex(int i, int j) {
return impl[i + width*j];
}
}

auto arr = Array2D!int(3, 3);
arr[0, 0] = 1;
arr[1, 1] = 2;
...

In the same vein you can write a type that declares opIndex with 3 or
more parameters, then you can get higher-dimensional indexing.

If you implement opDollar, then you can also use $ in your indexing,
e.g.:

struct MyArray(T) {
private int width, height;
...
int opSlice(size_t dim)() {
static if (dim == 0)
return width;
else
return height;
}
}

MyArray!int arr;
arr[$-2, $-3] = 1;


You can also implement slicing syntax like:

arr[2 .. $, 0 .. 3]

To do this, you need to overload .opSlice with two indices, returning
some object defining a range (i.e., encapsulates "2..$" or "0..3"), say
we call it IdxRange. Then overload opIndex to understand arguments of
type IdxRange. For example:

struct IdxRange { int start, end; }

struct MyArray(T) {
...
IdxRange opSlice(int start, int end) {
return IdxRange(start,end);
}

T opIndex(IdxRange colRange, IdxRange rowRange) {
... // return subarray here
}
}

Basically, this:

arr[2 .. $, 0 .. 3]

gets translated to this:

arr.opIndex(arr.opSlice(2, arr.opDollar!0),
arr.opSlice(0, 3));

It's up to you how to implement all of this, of course.  The language
itself doesn't ship a built-in type that implements this, but it does
provide the scaffolding for you to build a custom multi-dimensional
array type.


[...]
> And what is the difference between opIndexAssign and opIndexOpAssign?
[...]

opIndexAssign is for implementing operations of the form:

arr[x, y] = z;

opIndexOpAssign is for implementing operations of the form:

arr[x, y] += z;
arr[x, y] *= z;
// etc.

In the previous examples I had opIndex return ref, for simplicity, so
you could just assign to the array element via the ref. But if your
array implementation differentiates between looking up an element vs.
assigning to an element, then you'll want to provide your own
implementation of opIndexAssign and/or opIndexOpAssign:

struct MyArray(T) {
...
void opIndexAssign(T value, int x, int y) {
T* elem = lookupElement(x, y);
*elem = value;
}
void opIndexOpAssign(string op)(T value, int x, int y) {
T* elem = lookupElement(x, y);
mixin("*elem "~op~"= value;");
}
}


T

-- 
Try to keep an open mind, but not so open your brain falls out. -- theboz


Re: What is the difference between a[x][y] and a[x,y]?

2020-01-07 Thread Robert M. Münch via Digitalmars-d-learn

On 2020-01-07 17:42:48 +, Adam D. Ruppe said:


So [x][y] indexes an array of arrays.


Yes, that's what I understand. And both can be dynamic, so that I can 
have a "flattering" layout where not all arrays have the same length.



 [x,y] indexes a single array that has two dimensions.


Does this fix the dimension sizes? So I can't add a "row" or "column" 
at runtime?


What are the difference use-cases for these two? For example, I'm doing 
a grid widget but want to add/remove rows/columns. Can this only be 
done with a array-of-array? Is the memory continuous in the [x,y] case, 
whereas in the [x][y] this is not necessarily the case?



This can be kinda confusing because we often think of

int[4][4]

as being a 2d array, but the D language actually technically sees that 
as an array of arrays. So it is indexed with [x][y].


Yes, it's confusing as I don't understand the [x,y] case :-)

There is no built in multi-dimensional array, it is only syntax 
provided for library types to implement with the opIndexAssign 
overloads.


I don't get that sentence. Above you write "a single array that has two 
dimensions" which IMO is exactly a multi-dimensional array.


So the operator there like += or -= or *= etc become opAssign, whereas 
plain = is just plain Assign.


Got it. Thanks.

--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

Re: What is the difference between a[x][y] and a[x,y]?

2020-01-07 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 7 January 2020 at 17:38:59 UTC, Robert M. Münch wrote:
I read all the docs but I'm not toally sure. Is it that [x][y] 
is a 2D array-index, where as [x,y] is a slice?


So [x][y] indexes an array of arrays. [x,y] indexes a single 
array that has two dimensions.


This can be kinda confusing because we often think of

int[4][4]

as being a 2d array, but the D language actually technically sees 
that as an array of arrays. So it is indexed with [x][y].


There is no built in multi-dimensional array, it is only syntax 
provided for library types to implement with the opIndexAssign 
overloads.


And what is the difference between opIndexAssign and 
opIndexOpAssign?


foo[5] = x; // opIndexAssign
foo[4] += x; // opIndexOpAssign

So the operator there like += or -= or *= etc become opAssign, 
whereas plain = is just plain Assign.