Array rotate

2009-06-12 Thread yary
I am tickled pink to see an Array "rotate" method in the settings spec
S032, as I was thinking of writing up a little discussion on the very
topic.

Has there been discussion on using array rotate on multi-dimensional
arrays? Being able to pass in a vector as the amount to rotate would
be useful. eg-

my @a = (1,2,3 ; );
@a.rotate(0,1); # rotate down, @a is now (,1,2,3)
@a.rotate(1,0); # rotate right, @a is now (2,3,1;)

@a = (1,2,3 ; );
@a.rotate(1,1); # diagonal rotate, (; 2,3,1)

@a = (1,2,3 ; );
@a.rotate(1); # dimensionless rotate- does it flatten @a?
# is @a now (2,3,1;'b','c','a'), or ('c',1,2,3,'a','b')?

Thoughts?


Re: Array rotate

2009-06-12 Thread Jon Lang
On Fri, Jun 12, 2009 at 10:02 AM, yary wrote:
> I am tickled pink to see an Array "rotate" method in the settings spec
> S032, as I was thinking of writing up a little discussion on the very
> topic.
>
> Has there been discussion on using array rotate on multi-dimensional
> arrays? Being able to pass in a vector as the amount to rotate would
> be useful.

With a multi-dimensional array, a number of transforms can be considered:

* you can rearrange the elements along a given dimension (e.g., rotate
and reverse).
* you can rearrange the dimensions themselves (e.g., transpose).

-- 
Jonathan "Dataweaver" Lang


Re: Array rotate

2009-06-13 Thread John M. Dlugosz

Jon Lang dataweaver-at-gmail.com |Perl 6| wrote:

On Fri, Jun 12, 2009 at 10:02 AM, yary wrote:
  

I am tickled pink to see an Array "rotate" method in the settings spec
S032, as I was thinking of writing up a little discussion on the very
topic.

Has there been discussion on using array rotate on multi-dimensional
arrays? Being able to pass in a vector as the amount to rotate would
be useful.



With a multi-dimensional array, a number of transforms can be considered:

* you can rearrange the elements along a given dimension (e.g., rotate
and reverse).
* you can rearrange the dimensions themselves (e.g., transpose).

  

A short time ago, something similar came up.

I think the built-in's should stay simple, and a module (or several 
different ones) can exist to do comprehensive features for 
multi-dimensional arrays.  Designing that is really a separate project 
in itself, and it may shake out with use.


So keep it out of the core spec.

--John



Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread yary
Putting this in a new thread, as I'd like to discuss it separately
from refinements to Array.rotate

On Fri, Jun 12, 2009 at 10:11 AM, Jon Lang wrote:
> With a multi-dimensional array, a number of transforms can be considered:
>
> * you can rearrange the elements along a given dimension (e.g., rotate
> and reverse).

Hmm, we have an Array.reverse already, which I think flattens a
multi-D array before reversing it. Maybe it could take an adverb (:by
?) to let you specify which dimension(s) to reverse, though I can't
think of anything satisfactory to specify an axis set. Or maybe
there's a "reflect" method on Array for reversing along an axis, or
axes.

> * you can rearrange the dimensions themselves (e.g., transpose).

Reflecting on 2 or more axes creates a transposition. Maybe it makes
sense to have a separate transpose, defined in terms of reflection.

There's still more reshaping possibilities, some of which is already easy eg

my @tall[2;8] = (1 .. 16);
# tall  (1,2; 3,4 ; 5,6; ... etc)
my @wide[8;2...@tall;
# I think wide is (1 .. 8; 9 ..16)


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread yary
I think any 1D op could be transformed to "do the right thing" on a
multidimensional array, with some sort or hyperop or reduction
transform. Rotate, reverse, even add/subtract can be told "do your
thing along this vector" and return a usefully dimensioned result.

Need to work on other things at the moment but will get back to that
thought over the weekend...


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread Jon Lang
On Fri, Jun 12, 2009 at 10:58 AM, yary wrote:
>> * you can rearrange the dimensions themselves (e.g., transpose).
>
> Reflecting on 2 or more axes creates a transposition.

No, it doesn't:

@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

Reflecting on two axes would result in:

@a = (9, 8, 7; 6, 5, 4; 3, 2, 1);

Transposing the axes would result in:

@a = (1, 4, 7; 2, 5, 8; 3, 6, 9);

-- 
Jonathan "Dataweaver" Lang


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread Larry Wall
We also need to consider the "dimension" of referentiality.  I can see
three levels here.  Given

@a.mung

the .mung could return

A) a modified @a (treat @a as mutable)
B) a new array (treat @a as immutable)
C) a remapped array whose elements refer back to @a's elements

Currently .rotate is defined as A, but I could easily switch it to B,
so you'd have to write

@a.=rotate;

to rotate in place.  If we did that, then we could conceivably set
things up with more PDLish C semantics so that

@a .= mung  # A semantics
@b  = @a.mung   # B semantics
@b := @a.mung   # C semantics

This implies, however, that the copy semantics of = are sufficiently
clever to snapshot all the referenced values of @a before clobbering
@a in the case of either:

@a .= mung
@a = @a.mung

But list assignment really ought to be doing that in any case.

Maybe .push is really sugar for .=append, and unshift is really sugar
for .=prepend.

Larry


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread Damian Conway
Larry mused:

>   �...@a.mung
>
> the .mung could return
>
>    A) a modified @a (treat @a as mutable)
>    B) a new array (treat @a as immutable)
>    C) a remapped array whose elements refer back to @a's elements
>
> Currently .rotate is defined as A, but I could easily switch it to B,

I, for one, would vastly prefer to see the majority of (or even all)
container methods being non-mutating (with sugary shortcuts for the most
common mutators, if necessary).

A major advantage of having both .= and . in the language is that they
make it easy to see when something is (and isn't!) being altered in-place.
The fewer special-case "it-uses-plain-dot-but-it's-actually-a-mutator"
exceptions we have, the better.

In fact, I would even be happy with requiring @a.=push and @a.=shift, if
it meant that there were *no* special cases. One extra character is a
small price to pay for perfect SWIM (and not just "Say What I Mean",
the real benefit is the other SWIM: "See What I Meant").

Of course, this assumes that @a.=shift, @a.=push, etc. aren't actually
implemented with a copy-modifier-and-replace, but are optimized to
in-place mutators, under the hood.

Damian


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread Daniel Carrera

Damian Conway wrote:

In fact, I would even be happy with requiring @a.=push and @a.=shift, if
it meant that there were *no* special cases. One extra character is a
small price to pay for perfect SWIM (and not just "Say What I Mean",
the real benefit is the other SWIM: "See What I Meant").


I don't like @a.=shift. It looks like @a = @a.shift, which is of course 
not what you mean.


In addition, the current @a.shift is useful because it returns the 
element that was removed from the array, so you can do something with it:


loop {
@customers.push @c if (@c = new_customers());
serve_customer(@customers.shift);
}

I'm sure the more experienced people can suggest a better example.

Daniel.


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread Larry Wall
On Sat, Jun 13, 2009 at 01:25:23AM +0200, Daniel Carrera wrote:
> Damian Conway wrote:
>> In fact, I would even be happy with requiring @a.=push and @a.=shift, if
>> it meant that there were *no* special cases. One extra character is a
>> small price to pay for perfect SWIM (and not just "Say What I Mean",
>> the real benefit is the other SWIM: "See What I Meant").
>
> I don't like @a.=shift. It looks like @a = @a.shift, which is of course  
> not what you mean.

He meant unshift, I suspect.

Nevertheless, for any major methods borrowed from Perl 6, I'm not
inclined to change them that drastically.  Much more likely to
define them as sugar for the more general list operators:

.push   means   .=append
.unshiftmeans   .=prepend
.splice means   .=impend:-)

or some such.

Larry


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread Matthew Walton
On Sat, Jun 13, 2009 at 1:08 AM, Larry Wall wrote:
> Nevertheless, for any major methods borrowed from Perl 6, I'm not
> inclined to change them that drastically.  Much more likely to
> define them as sugar for the more general list operators:
>
>    .push       means   .=append
>    .unshift    means   .=prepend
>    .splice     means   .=impend        :-)
>
> or some such.

That makes sense to me. I'd very much like it if the fundamental
methods on most data types were non-mutating - string manipulation,
list munging etc. Along with having lazy lists, that gives us a good
dose of tricks from the functional world we can do, and with .= and
(hopefully) some clever bits in the compiler which can handle it
effectively (as in performance-wise), it's no hassle to convert any
non-mutator to a mutator. Syntactic sugar for really common mutating
cases, as in other methods which do 'the same thing but mutated' is of
course fine (particularly when they have sensible/familiar names,
which implies to my mind that the operation makes sense).

Although some things may be able to be implemented far more
efficiently if they know that they're being called with infix:<.=> and
not with infix:<.>.

method munge($self is ro:) { } # infix:<.> case
method mung($self is rw:) { } # infix:<.=> case

?

Marginally inspired by C++ const methods. Of course, a potential
problem here is that they might want different return types as well -
but maybe our multis are fine with that, and maybe this is just some
crazy dream caused by waking up too early on a Saturday morning and
thinking about Perl before breakfast.

Matthew


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-13 Thread Daniel Carrera

Larry Wall wrote:

Nevertheless, for any major methods borrowed from Perl 6, I'm not
inclined to change them that drastically.  Much more likely to
define them as sugar for the more general list operators:

.push   means   .=append
.unshiftmeans   .=prepend
.splice means   .=impend:-)

or some such.


I like those. I feel similar to Matt W. I kind of like .push and 
.unshift the way they are (probably just habit) But I can appreciate 
that non-mutating alternatives might open a new class of algorithms from 
the functional world.


Daniel.


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-13 Thread Jon Lang
On Fri, Jun 12, 2009 at 11:23 PM, Matthew
Walton wrote:
> Although some things may be able to be implemented far more
> efficiently if they know that they're being called with infix:<.=> and
> not with infix:<.>.

Last I checked, Perl 6 had some types that are mutating and others
that aren't (e.g., List and Array, I think).  An additional benefit of
setting up the "primitive methods" as non-mutating is that you
increase the amount of functionality shared by the two: if all
mutating methods are syntactic sugar for non-mutating counterparts,
then non-mutating types will be able to do everything that their
mutating brethren can do (except mutate, of course).  E.g., a List can
push, unshift, splice, etc; an Array can append, perpend, impend, etc.

And if you want to do purely functional programming, you can do so by
restricting yourself to the use of non-mutating types and staying away
from those methods that have side effects (which should [i]also[/i] be
easily identifiable).  Indeed, this same notion of ensuring that pure
functional versions of mutating methods exist should also apply to
methods with side effects: as much as possible, if a method is
designed to perform a calculation and to produce a side effect, there
should also be an equivalent method that merely performs the
calculation.  Even better would be to segregate the methods that
produce side effects from the methods that perform calculations.

Am I making sense?

-- 
Jonathan "Dataweaver" Lang


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-13 Thread John M. Dlugosz

Larry Wall larry-at-wall.org |Perl 6| wrote:

We also need to consider the "dimension" of referentiality.  I can see
three levels here.  Given

@a.mung

the .mung could return

A) a modified @a (treat @a as mutable)
B) a new array (treat @a as immutable)
C) a remapped array whose elements refer back to @a's elements

Currently .rotate is defined as A, but I could easily switch it to B,
so you'd have to write

@a.=rotate;

  
Having some operation XX return a new object and using =.XX do it "in 
place" would be consistent with the way other things are shaping up.  
But people expect push to work like they are used to, and the exported 
push, called as a sub not as a method, would be copying. 


In void context it could give an error.

   push @a, $x;# what's the point?

if we had a general way to decorate the sub definition to day "must not 
use in void context".


As expressed already in the synopses, the function called for 
@a.=push($x); can be written specially to handle the in-place case, 
rather than have to assign back after copying like the auto-generated 
case would.  (What exactly "define a self.push operator" means needs to 
be clarified in S12.  Is that not the normal sub syntax?)  In other 
words, defining self.push would be the implementation that Perl 5 push 
is now.




to rotate in place.  If we did that, then we could conceivably set
things up with more PDLish C semantics so that

@a .= mung  # A semantics
@b  = @a.mung   # B semantics
@b := @a.mung   # C semantics

  
That third one would be rather inefficient.  The returned array would 
need to be set up as an array of binding proxies, if the original wasn't 
set up as an array of item containers, just in case it gets bound to 
something (or used as part of a larger expression) rather than assigned.


I'm looking at this general issue right now (musing over it the last 
week actually) and although it's nowhere near done yet, you can see 
Figure 1 at  
and the text that is taking shape around it.





This implies, however, that the copy semantics of = are sufficiently
clever to snapshot all the referenced values of @a before clobbering
@a in the case of either:

@a .= mung
@a = @a.mung

But list assignment really ought to be doing that in any case.

  
Wow.  The overarching logic for list assignment would have to compare 
the containers and the arguments in the capture before doing the list 
assignment to each container, in order to avoid cloning all the 
containers on the right first in the general case.  It can't just copy 
values out because they may contain iterators or be lazy or be infinite.


--John



Re: Multi-d array transforms (was Re: Array rotate)

2009-06-13 Thread John M. Dlugosz

Daniel Carrera daniel.carrera-at-theingots.org |Perl 6| wrote:
In addition, the current @a.shift is useful because it returns the 
element that was removed from the array, so you can do something with it:



The change to the library synopses was checked in before you posted 
that, if I recall the delta correctly.


But you bring up a point:  that is indeed the common idiom from Perl 5. 


That brings up the following radical idea:

Have no method named shift at all.  Shift etc. will be a non-member sub 
brought in through


   use legacy;

and designed to work just like Perl 5, for that express purpose.  The P6 
way of doing it would be to not do that: use iterators rather than 
destructivly going through the array, or use decomposition to do things 
in a more functional way, or use the more general syntax to delete one 
element from the beginning, in-place or copy as indicated.


--John



Re: Multi-d array transforms (was Re: Array rotate)

2009-06-13 Thread Larry Wall
On Sat, Jun 13, 2009 at 02:49:10PM -0500, John M. Dlugosz wrote:
> Wow.  The overarching logic for list assignment would have to compare  
> the containers and the arguments in the capture before doing the list  
> assignment to each container, in order to avoid cloning all the  
> containers on the right first in the general case.  It can't just copy  
> values out because they may contain iterators or be lazy or be infinite.

Well, that's not really a problem, as long as the same semantics
are preserved.  All you need to do is cut loose the contents of the
container completely to the mercy of GC, build a new one with the
appropriate structure, then copy values in from the assignment's RHS.
The only reason Perl 5 couldn't do it this way is that the idiot who
wrote it prematurely optimized values on the stack so that they didn't
need to be reference counted. :)

Larry


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-13 Thread John M. Dlugosz

Larry Wall larry-at-wall.org |Perl 6| wrote:

On Sat, Jun 13, 2009 at 02:49:10PM -0500, John M. Dlugosz wrote:
  
Wow.  The overarching logic for list assignment would have to compare  
the containers and the arguments in the capture before doing the list  
assignment to each container, in order to avoid cloning all the  
containers on the right first in the general case.  It can't just copy  
values out because they may contain iterators or be lazy or be infinite.



Well, that's not really a problem, as long as the same semantics
are preserved.  All you need to do is cut loose the contents of the
container completely to the mercy of GC, build a new one with the
appropriate structure, then copy values in from the assignment's RHS.
The only reason Perl 5 couldn't do it this way is that the idiot who
wrote it prematurely optimized values on the stack so that they didn't
need to be reference counted. :)

Larry

  
I agree, if "the contents" include the iterators and code blocks and 
whatnot that make up the concrete types of the things on the right.  But 
if it's not a built-in standard type, it might require a call to the 
general shallow-copy clone of the object.


  my @A is CustomContainer;
  my @B[7];  # fixed size
  ...
  @B,@A,@C = @A,@B;

The compiler doesn't know how to juggle the internals of @A because it 
is not a standard type.  This needs to become:


   my @temp1 = @A.clone;
   my @temp2 = @B.clone;
   @B,@A,@C = @temp1,@temp2;

and assume that the compiler might optimize the case with @B through 
innate knowledge, and possibly inline and optimize over the calls for @A.




Premature optimization is the root of all evil.

But... design the semantics so there is some hope of optimization.  That 
might entail designing in some features of Positional that will be used 
by this construct, as more efficient than just calling .clone().


OTOH, machines are a million times faster than what Perl 4 originally 
ran on.


Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-12 Thread Daniel Ruoso
Ok, There's one thing that is not clear in the thread, which is when an
array is multidimensional or not...

For instance:

 @a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

Will produce a flatten array, because list assignment causes flattening,
so the dimensionality was lost.

It is important to remember that this was a change in the spec that
happened some time ago. Before that, @a and @@a did refer to the same
variable, but this is no longer the case. Now @a and @@a are different
variables (in fact the @@ sigil is probably going to be replaced, since
it's not just "list slice" but it's actually a capture)

So, in the @a = (1,(2,(3,4)); example, @a will be a flat list with 4
elements.

So, how do I deal with a multidim array? Well, TIMTOWTDI...

 my @a = 1,[2,[3,4]];
 say @a[1][1][1];
 say @a[1;1;1]; # I'm not sure this is correct

Or.. (I'm using the proposed capture sigil here, which has '@%a' as its
expanded form)

 my ¢a = 1,(2,(3,4);
 say ¢a[1][1][1];
 say ¢a[1;1;1];

I think that makes the semantics of the API more clear...

daniel



Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-12 Thread Jon Lang
On Fri, Jun 12, 2009 at 11:51 AM, Daniel Ruoso wrote:
> Ok, There's one thing that is not clear in the thread, which is when an
> array is multidimensional or not...
>
> For instance:
>
> �...@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);
>
> Will produce a flatten array, because list assignment causes flattening,
> so the dimensionality was lost.

Right.  I should have said:

@@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

-- 
Jonathan "Dataweaver" Lang


Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-12 Thread Daniel Ruoso
Em Sex, 2009-06-12 às 11:52 -0700, Jon Lang escreveu:
> On Fri, Jun 12, 2009 at 11:51 AM, Daniel Ruoso wrote:
> > Ok, There's one thing that is not clear in the thread, which is when an
> > array is multidimensional or not...
> > For instance:
> >  @a = (1, 2, 3; 4, 5, 6; 7, 8, 9);
> > Will produce a flatten array, because list assignment causes flattening,
> > so the dimensionality was lost.
> Right.  I should have said:
> @@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

The important point here is that it means we're dealing with a different
type, so it can actually behave differently, so "@@a.rotate" would
rotate the first dimension only..

maybe @@a.rotate(1;1) would mean to rotate by 1 in the first dimension
and by 1 in the second, producing

 (5, 6, 4; 8, 9, 7; 2, 3, 1)

daniel




Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-12 Thread Larry Wall
On Fri, Jun 12, 2009 at 04:00:10PM -0300, Daniel Ruoso wrote:
: Em Sex, 2009-06-12 às 11:52 -0700, Jon Lang escreveu:
: > On Fri, Jun 12, 2009 at 11:51 AM, Daniel Ruoso wrote:
: > > Ok, There's one thing that is not clear in the thread, which is when an
: > > array is multidimensional or not...
: > > For instance:
: > >  @a = (1, 2, 3; 4, 5, 6; 7, 8, 9);
: > > Will produce a flatten array, because list assignment causes flattening,
: > > so the dimensionality was lost.
: > Right.  I should have said:
: > @@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);
: 
: The important point here is that it means we're dealing with a different
: type, so it can actually behave differently, so "@@a.rotate" would
: rotate the first dimension only..
: 
: maybe @@a.rotate(1;1) would mean to rotate by 1 in the first dimension
: and by 1 in the second, producing
: 
:  (5, 6, 4; 8, 9, 7; 2, 3, 1)

I think captures are a bit of a red herring here.  Arrays can be shaped
without the @@ sigil, and that is part of its type, so assignment to
@a and @.rotate can also do the right thing.

The @@ context was originally just a way of declaring a context that turns
nested captures into a multidimensional array at binding or
coercion time.  So

@a := @@(1,2,3; 4,5,6; 7,8,9);

used to be defined as the same as

@a := [[1,2,3], [4,5,6], [7,8,9]];

Treating @@ as a capture sigil would make @@ coercion a no-op.
So perhaps @@ isn't the Texas form of a capture sigil after all.

Alternately, we leave @@ (or @%) meaning ¢ and instead let some
other syntax take over the "pay attention to the capture's structure"
semantics from @@.  Maybe it's another use for the zen slice:

@a   = (1,2,3; 4,5,6; 7,8,9); # 1..9
@a[] = (1,2,3; 4,5,6; 7,8,9); # [1,2,3], [4,5,6], [7,8,9]

Interestingly, that would mean that

@a   = 1,2,3;   # 1,2,3 3 elems
@a[] = 1,2,3;   # [1,2,3]   1 elem!

much like subscripts assume .[1,2,3] is a 1-dim slice of three
elements, not a 3-dim vector pointing to a single element.

There's something slightly pleasing about the equivalence

@a = [1,2,3];
@a[] = 1,2,3;

Larry


Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-13 Thread John M. Dlugosz

Larry Wall larry-at-wall.org |Perl 6| wrote:

Alternately, we leave @@ (or @%) meaning ¢ and instead let some
other syntax take over the "pay attention to the capture's structure"
semantics from @@.  Maybe it's another use for the zen slice:

  



"pay attention to the capture's structure" is a can of worms.  As things 
stand now in the Synopses, you get a lot of empty extra wrappers around 
things.  You don't want to keep that exact!  When you are not doing 
full-blown flattening, which levels in the morphology are "extra" due to 
passing though functions or grouping parens, and which are intended to 
be part of the final structure?  Since the crazy stuff inside the 
capture is usually invisible, people will have a hard time using that 
correctly.


(A literal reading of the synopses now gives us the morphology 
illustrated at , and I 
hope to remove _some_ of those extra wrappings through refinement of the 
rules when I get around to studying that in detail.)


My thoughts at this point is that "slice context" needs to *know* it is 
being rolled up into a final result that is a 2-dim array.  The rules 
for that will strip out extra wrappers except where it really is 
significant, designed through use cases of seeing what common constructs 
actually produce.


A shaped array knows what needs to be poured into it, so the RHS can be 
flattened.  The single-dim array is just a special case of that; it 
generalizes to higher dimensions just fine, as seen in languages like APL.


A smart shaped assignment, to handle containers with * in other than the 
highest position, can be supplied as part of a multi-dim array Module, 
designed separately along with a coherent set of features such as 
general vector-driven transposes etc.


--John



Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-13 Thread John M. Dlugosz

Daniel Ruoso daniel-at-ruoso.com |Perl 6| wrote:

So, how do I deal with a multidim array? Well, TIMTOWTDI...

 my @a = 1,[2,[3,4]];
 say @a[1][1][1];
 say @a[1;1;1]; # I'm not sure this is correct

  
I think that it should be.  That is, multi-dim subscript is always the 
same as chained subscripts, regardless of whether the morphology is an 
array stored as an element, or a multi-dim container, or any mixture of 
that as you drill through them.


I've not written out a full formalism yet, but I've thought about it.
The multi-dim subscript would return a sub-array if there were fewer 
parameters than dimensions, an element if exact match, and recursively 
apply the remaining subscripts to the element if too many.




Or.. (I'm using the proposed capture sigil here, which has '@%a' as its
expanded form)

 my ¢a = 1,(2,(3,4);
 say ¢a[1][1][1];
 say ¢a[1;1;1];

I think that makes the semantics of the API more clear...

daniel


  

The plain Array would work too, in the nested morphology:

   my @a = 1,[2,[3,4]];

@a has 2 elements, the second of which is type Array.

   say @a[1][1][1];

naturally.

   say @a[1;1;1];

means the same thing, intentionally.

   say @a[1][1;1];
   say @a[1;1][1];

ditto.

--John