Negative array indices are wrong
Some programming languages, like Python, Ruby, and Perl, support array indexing with negative values. Doing so will index “from the right”, so for instance array[-1]
will be the last element and array[-2]
the second-to-last.
We can succinctly summarize the behaviour with the following identity:
array[-abs(n)] == array[len(array) - abs(n)]
Convenient! Want the nth value of an array? Boom: array[n]
. Want the nth-from-last? Bam: array[-n-1]
rk.
Often one can write array[-n-1]
succinctly as array[~n]
, utilizing bitwise NOT and twos-complement integer representation!
However, I claim that this is the end of the niceness of negative array indices.
The issue is that negative array indices do more than just provide nice syntax. If, for instance, an index is derived from the user ...
n = input()
print(array[n])
... We probably don’t intend for an input value of -1
to print out the last item of the array, and the user probably would by surprised by that behaviour as well.
Actually, I would claim that the vast majority of code which makes use of negative array indices does so by negating an expected-nonnegative index, and almost never by passing around a possibly-negative index. In other words, my bet is that 99% of code looks either like array[n]
, with n >= 0
expected, or array[-n]
with n >= 1
expected, and almost never like array[n]
with the explicit consideration that n
might be negative.
This easy oversight can turn into subtle bugs. And for what? Pretty syntax.
Super simple: provide different methods for indexing from the left and from the right. array.from_right(n)
is not much more difficult to write than array[-n]
—and certainly no less readable!