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

Reply via email to