Buddha Buck wrote:
> > Reading through the examples left me wondering about some
> > technicalities:
> >
> > > @t[|i;|j] = @a[|j;|i]; # transpose 2-d @a
> >
> > Written like this it would require that @a is exact 2-dim, i.e. it would
> > not just swap the first two dims of any n-dim array? I suppose if I'd
> > want that I'd write
> >
> > @t[|i;|j;] = @a[|j;|i;]; # trailing ';' implies there might be
> > trailing dims
>
> I will confess, operations on general multidimensional arrays were not
> something I had considered when I originally had this idea. The
> problem I see with your @t[|i;|j;] example is that it isn't clear that
> the trailing dims for @a and @t will have tied iterators. I.e., if @a
> is defined with "my @a :bounds (3,3,3);", which of these two should be
> considered equivilant?
>
> @t[|i;|j;|k] = @a[|j;|i;|k]; # or...
> @t[|i;|j;|k] = @a[|j;|i;|l];
>
> Arguments could be made for either one.
As I mentioned earlier, the trailling ';' is unnecessary. The reason why
(all premises taken directly from the array RFCs:
----
LOLs and multidimensional arrays share all syntax.
$a[$i] and $a[[$i]] are equivalent, except that [[]] automatically
dereferences. Therefore:
my @a = (1,2);
$a[1] == 2;
$a[[1]] == 2;
my @b = ([1,2],[3,4]);
$b[1] == [3,4];
@b[[1]] == (3,4);
$a[[$i, $j]] is equivalent to $a[$i][$j].
@t[|i;|j] = @a[|j;|i] is equivalent to:
foreach $i (@a) {
foreach $j (@$i) {
$t[$j][$i] = $a[$i][$j];
}
}
Regardless of whether $a[$i][$j] is a list ref, or a scalar, this loop will
work just fine.
The innermost dimensions of a 3d array are (semantically) list refs.
Therefore the implicit loop works on 3d arrays.
----
The key to making this implicit loop syntax work is to consistantly apply
the semantics about the loop that is being created. I like Buddha's proposal
that the width of the generated loop is the smallest sub-expression that
contains all of the iteration variables.