4 ms·
Values take up space. When you manipulate a value or pass it around, it makes no sense to sometimes refer to the beginning of the value and sometimes to the end
by sfink 2y ago
Values take up space. When you manipulate a value or pass it around, it makes no sense to sometimes refer to the beginning of the value and sometimes to the end.
It makes a little more sense if you have an array of something other than plain integers. Let's say you have 2-tuples:
0 1 2 3 4 5
| (0, 1) | (1, 1) | (1, 2) | (2, 3) | (3, 5) |
-5 -4 -3 -2 -1 -0
or perhaps a better display would be more memory-based, where a tuple is represented as a pair of bytes:
0 1 2 3 4 5
00010101010202030305
-5 -4 -3 -2 -1 -0
Now -3 clearly refers to the beginning of an array element. At least I wouldn't expect -3 to refer to (1, 1), even though I'm mentally traversing right to left for negative indexes.
Or another way to think about it: arr[5] does not exist in the above example. It's the end of the array, and the end is exclusive. Negative indexes count from the end. -0, as a result, refers to the (unmodified) end, which is the nonexistent thing, same as arr[5].
And yet another way: think of positive indexes as going forward, negative as going back. Imagine a syntax arr[3][-2] where arr[3] gives you the subarray starting at offset 3. (In C or C++, this would be like (&arr[3])[-2] with an array type that supported negative indexes, which implies it tracks subarray length.) Where should you end up? Start with the simpler case of arr[3][-0] -- clearly that should be the same as arr[3], not arr[2], if you are "going back 0". And if you're starting out with 0-based indexes, then the "going forward"/"going back" interpretation is inescapable.
As a bonus, arr[-n] is the same as arr[arr.length() - n]. But that's just a lucky happenstance; I wouldn't argue that the semantics of negative indexes should depend on it. Well... one could argue that arr[arr.length()] is the (nonexistent, exclusive) end.