On 1/30/07, [EMAIL PROTECTED] wrote in "[svn:perl6-synopsis] r13549
- doc/trunk/design/syn":
+It has become the custom to use negative subscripts to indicate counting
+from the end of an array. This is still supported, but only for unshaped
+arrays:
+For shaped arrays you must explicitly refer to the current endpoint
+using C<*>, the C<Whatever> object:
Bringing us back to the discussion of ordinals from a few years ago...
On 9/6/04, Larry Wall wrote in "Re: Synopsis 9 draft 1":
Another possibility is that .[] always forces the "normal" view of
an array as 0-based, and if you want non-0-based arrays you have to
use the .{} interface instead, on the assumption that strange
subscripts
are more like hash keys than ranges of integers. Certainly if you
have a sparse array with keys like 1,2,4,8,16,32... you have a
situation that's more like a hash than an array. A sparse array
might not even give you the .[] interace. The presence of a .[]
interface might signal the ability to process contigous ranges, even
if those ranges are offset from the .{} range.
Such an approach would have the benefit that a module could simply
treat all its arrays as 0-based .[] arrays, and if you happened to
pass a non-0-based .{} array in, it would still work, albeit with
0-based indexes instead of whatever shape the .{} interface uses.
I don't think anything came of that, but the more I think about it,
the more I like it. Sparse/negative/etc. array indices really are
more like hash-keys than ordinals, so why don't we go ahead and have
two different ways to look up elements from arrays and hashes?
Also, this would solve a problem I've been wondering about with
"funny" shapes being lexically scoped. From S09:
You can pretend you're programming in Fortran, or awk:
my int @ints (1..4, 1..2); # two dimensions, @ints[1..4; 1..2]
Note that this only influences your view of the array in the current
lexical scope, not the actual shape of the array. If you pass this
array to another module, it will see it as having a shape of
(0..3,0..1) unless it also declares a variable to view it
differently.
However, what if you pass the funny array along with a (funny) index?
E.g. our @flavours (1..32);
my $favourite = get_fave(@flavours); #returns index of selected flavour
warn "Sorry, all out of @flavours[$favourite]!"
unless in_stock(@flavours, $favourite);
Which means that you'd be checking for the wrong thing to be in
stock. (Actually, you'd also get the wrong index back from
get_fave(), so in this limited example, the two errors would probably
cancel each other out, but the warning message will print the wrong
flavour because it's using the shifted index.)
Of course, thinking of arrays as numbered consecutively from 0 to n
will probably result in speaking P6 with a P5 accent: better to "for
[each]" over an array rather than loop across index numbers. If you
needed to use the index values, there was no alternative in P5 (or C,
etc.), but now we can use @foo.keys or .kv, and get the actual
indices even when the array is sparse, or uses negative subscripts.
But there will still be a need to traverse arrays ordinally, so I
think reserving [] lookups for this purpose is a good idea. Then
it's always clear whether you're using the "funny" (i.e. {}) keys or
the "old-fashioned" (i.e. []) ordinals. And negative subscripts can
always count backwards inside [] (and just be actual negative keys
inside {}).
Then we wouldn't need * to count backwards, although it's still
useful to allow us to count past the end of an array. There are all
sorts of variations on this scheme, such as whether * is the last
element or the one after that, etc., or whether 0 should be the first
element or the last, and so on.
(And of course, if arrays can be indexed with {}, then hashes can be
indexed with [] -- dunno if there's any point for ordinary hashes,
but it certainly could be useful with ordered ones.)
-David