|P is for Practical|
Re^2: why the array index has to start at 0?? (Perl!)by tye (Cardinal)
|on Jun 24, 2009 at 05:03 UTC||Need Help??|
Actually, you bring up points that lead me to prefer that Perl index such things starting at 1. I understand the original quoted justification for using 0. And it makes sense particularly in C++, where we have pointers to arrays and pointer arithmetic and "beg <= i < end" ranges.
We don't have any of those things in Perl, so I find the argument pretty pointless when applied to Perl.
But there are several relevant things we have in Perl. 0 is false. $x[-1] is the last element of an array. $x[-0] can't sanely be made to be the last element of an array. By starting at 0, index() fails by returning a true value and is forced to return "0 but true" for one success case. I'd be happy for $x[undef] to return undef, preserving the undefinedness. This becomes easy if $x is likewise 'reserved'.
And, in Perl, we usually don't write:
We are much more likely to write something of the form:
And by starting at 1 we don't need the ugly $#array addition and just write what makes so much more sense to humans:
Give a child a handful of items and ask them to hand them back to you, numbering them as they go. They won't number them from zero to $N-1. The first item will be number 1, of course. That is why we call it the "first" item, the "1st" item, not the zeroth item. "zeroth" is a word you almost never hear from ordinary citizens.
I expect to hear "zeroth" used in connection with unbounded sequences, for example: "the zeroth power of 2". Perl arrays are not unbounded. They are indexed with values from 0..$#array and -@array..-1. Ugh. It would be so much nicer to have them indexed with values from 1..@array and -@array..-1. I would also appreciate the separation between those ranges so that an off-by-one error in one range can't accidentally land you in the other range.
I appreciate the elegance with which K&R resolved the long-running argument for the C language, by defining array[i] as a syntactic alias for *(array+i) and thus making array indices unambiguously offsets and therefore something that must start from 0.
I appreciate the elegance of "beg <= i < end" range definitions. I've used them quite a bit in C++. I've even used them in Perl code. But part of the point of such things is that 'end' is defined as 'the mythical item just off the end of our list'. $N+1 makes perfect sense as that. So I find "1 <= i < N+1" an even clearer representation of such ranges. It even leads to more regularity in defining such ranges, because they all become "start <= i < start+length" (which might lead you to write "1 <= i < 1+N").
So I've long found the arguments much more convincing for starting from 1 in Perl. Perl isn't glorified assembly (how I've heard many people refer to C) which is why it doesn't have pointer arithmetic which is also why it should number things like real humans do, not like how machine language would.
As to "zero as a most natural number", I think that belittles the fundamental innovation that was its invention/discovery long after 1 and its followers were being heavily used.
But all of this is pretty academic (as in "useless") in relation to Perl. Perl long ago standardized on numbering things starting from 0. That decision is not easily undone (or redone).