Comment by geocar
1 year ago
> Why shouldn’t an array at the smallest possible index correspond to the beginning of the array?
Because then there is no good way to refer to the index before that point: You are stuck using -1 (which means you can't use it to refer to the end of the array), or null (which isn't great either).
> every programming language I know of that supports the concept of unsigned integer
Surely you know Python which uses a signed integer as an index into their arrays: list[-1] is the last element of a list. If they only used one-based indexing then list[1] would be the first and that would be nicely symmetrical. It would also mean that list[i-1] would NEVER refer to a value after ‹i› eliminating a whole class of bugs.
> It’s also very natural to think of arr[i] as “i steps past the beginning of arr.”
I think it's more natural to think of arr[i] as “the ‹i›th element of arr” because it doesn't require explaining what a step is or what the beginning is.
The exact value of ‹i› matters very little until you try to manipulate it: Starting array indexes at one and using signed indexes instead of unsigned means less manipulation overall.
> find the convention used in many countries of numbering building floors starting with zero to be more logical
In Europe, we typically mark the ground-floor as floor-zero, but there are often floors below it just as there are often floors above it, so the floors might be numbered "from" -2 for example in a building with two below-ground floors. None of this has anything to do with arrays, it's just using things like "LG" or "B" for "lower ground" or "basement" don't translate very well to the many different languages used in Europe.
The software in the elevator absolutely doesn't "start" its array of sense-switches in the middle (at zero).
> In Europe, we typically mark the ground-floor as floor-zero,
_Western_ Europe. Eastern Europe prefers 1-based numbering. The reason, typically assumed, is that thermal isolation, required due to colder winters, causes at least one stair segment between entrance and the sequentially first floor.
Python might have used array[~0] instead, where ~ is required, to indicate end-of-list 0-based indexing.
But I guess they wanted to iterate from the end back [-1] to the start [0], making it easy to implement a rotating buffer.
> Python might have used array[~0] instead
This is what was once added to C#: arr[^idx], when this ^idx is mapped to a special object, typically optimized then out. arr[^0] means the last element.
[^n] indexing is mapped to an 'Index' struct by Roslyn which can then be applied to any array or list-shaped type (it either has to expose Index-accepting indexer, or a plain integer-based indexer and Count or Length property. There really isn't much to optimize away besides the bounds check since there are no object allocations involved.
A similar approach also works for slicing the types with range operator e.g. span[start..end].
> I think it's more natural to think of arr[i] as “the ‹i›th element of arr” because it doesn't require explaining what a step is or what the beginning is.
Yes, but if you will eventually need to do steps on your array, you better opt for the framework that handles them better. I agree, that if your only task is to name them, then 1 based indexing makes more sense: you do that since diapers, and you do that with less errors.