On 2/27/07, Jonathan Lang wrote:
David Green wrote:
So I end up back at one of Larry's older ideas, which basically is:
[] for counting, {} for keys.
What if you want to mix the two? "I want the third element of row
5". In my proposal, that would be "@array[5, *[2]]"; in your
proposal, there does not appear to be a way to do it.
Unless the two approaches aren't mutually exclusive: "@array{5,
*[2]}". [...] Since this is an unlikely situation, the fact that
nesting square braces inside curly braces is a bit uncomfortable
isn't a problem: this is a case of making hard things possible, not
making easy things easy.
Oh, good point. Yes, I think that mixing them together that way makes sense.
It also suggests that you could get at the named keys by applying {} to *:
%foo[0, 1, *{'bar'}]; #first column, second row, "bar" layer
The one gotcha that I see here is with the possibility of
multi-dimensional arrays. In particular, should multi-dimensional
indices be allowed inside square braces? [...] With that promise,
you can always guarantee that the wrap-around semantics will work
inside [], while nobody will expect them to work inside {}.
Right, I don't see a problem with handling any number of dimensions that way.
Furthermore, you could do away with the notion of "shaped vs.
unshaped": just give everything a default shape. The default shape
for arrays would be '[*]' - that is, one dimension with an
indeterminate number of ordinals.
Meanwhile, shapes for {} would continue to use the current syntax.
'[$x, $y, $z]' would be nearly equivalent to '{0..^$x; 0..^$y; 0..^$z}'.
Agreed.
it can work in the usual way: start at 0, end at -1. It is useful
to be able to count past the ends of an array, and * can do this by
going beyond the end: *+1, *+2, etc., or before the beginning: *-1,
*-2, etc. (This neatly preserves the notion of * as "all the
elements" -- *-1 is the position before everything, and *+1 is the
position after everything else.)
Regardless, I would prefer this notion to the "offset from the
endpoint" notion currently in use. Note, however, that [*-1]
wouldn't work in the ordinals paradigm; there simply is nothing
before the first element. About the only use I could see for it
would be to provide an assignment equivalent of "unshift":
'@array[*-1] = $x' could be equivalent to 'unshift @array, $x'. But
note that, unlike the 'push'-type assignments, this would change
what existing ordinals point to.
I figured that *-1 or *+1 would work like unshift/push, which
effectively does change what the ordinals point to (e.g. unshifting
a P5 array). If the array is not extensible, then it should fail in
the same way as unshift/push would.
Meanwhile, {*-1} would only make sense in cases where keys are
ordered and new keys can be auto-generated. Note also that {*+$x}
is compatible with {*[$x]}: the former would reference outside of
the known set of keys, while {*[$x]} would reference within them.
Exactly.
-David