Hi Nelson —
Good question. x = x.reindex(1..5);
is doing something, just nothing interesting. Specifically, x.reindex(1..5)
creates a new array that’s a view of x
's elements that’s indexed using 1..5
rather than 0..4
. E.g., if you wrote (x.reindex(1..5))[0]
(i.e., you tried to access element 0 of this array), you’d get an out-of-bounds error. Similarly, (x.reindex(1..5))[5]
would work.
Then, that view you’ve created is assigned to x
which still has the original indices 0..4
. This is legal because Chapel permits assignment between rectangular arrays with different indices if they have the same size and shape. As a clearer example, the following code is legal Chapel:
var A: [0..4] real;
var B: [1..5] real;
var C: [1..10 by 2] real;
A = B; // copies B's five elements to A; doesn't change A's indices
A = C; // copies C's five elements to A; doesn't change A's indices
So your assignment is effectively like the A=B
case above, copying the elements (which were already x’s elements, so that’s not very interesting), but not copying/changing/modifying the indices.
A more typical way to use a reindexed expression is using a ref
declaration, like:
ref x1 = x.reindex(1..5);
at which point your loop would work as expected (replacing x
with x1
):
for i in 1…5 do writeln(x1[i]); // runtime error on x[5]
Another common pattern is to pass the reindex expression into a function that takes an array argument, where the function will treat it like any other array.
One final note: reindex views of arrays result in overhead, both to set up the view, and on every access (because the logical reindexing is computed on every access). So think of this feature as a convenience feature rather than one you’d want to lean on heavily in performance-sensitive code.
The “real” way to redefine an array’s domain is to declare the domain as a variable:
var D = {1..5};
var A: [D] real = [i in 1..5] i;
and then to re-assign the domain:
D = {0..4};
however, it’s important to note that for a given index i
in both the old and new domain value, A[i]
is logically preserved across this assignment. I.e., this isn’t a memory-focused re-alloc command, but a logical change of the array’s indices, preserving any elements that are in both the old and new index set. Thus, in the code above, the resulting values of A are:
0 1 2 3 4
where A[1..4]
preserved their original values, A[5]
was dropped on the floor, and A[0]
just happens to be 0
since that’s the default value for integers (i.e., changing the domain to -1..6
would similarly set elements A[-1]
and A[6]
to 0
).
Hope this is helpful,
-Brad