That's for languages that can't define arrays with custom start/stop indexes. But those that have custom indexes they can very easily expand/implement as helper class (for example array.indexFromLast(1) which means array[Length(array)]. This way you can have best of both worlds.
Surely if your language has custom indexes / ranges `Length(array)` is completely broken and the language provides something like "Index`Last" you can hook on?
Because an array with indexes [3, 7) has length 4, but 4 is not the index of the last element.
That's what Ada does, yes. You'd let the array (or whatever collection) do the work for you:
for I in A'Range loop
A(I) = A(I) + A(I);
end loop;
Whatever the range is, this will work. If you really need the first and last elements or want to be explicit:
Start := A'First;
End := A'Last;
And if the type of the range (since any discrete type can be used) doesn't support simple incrementing with +1 or similar, you can use 'Succ to step through:
Index := A'First;
Index := Whatever_Type'Succ(Index);
Also 'Pred to work backwards. Those can be wrapped up in a simpler function if desired.
And with its array slice mechanisms, Ada is one of the most easy/productive language to handle arrays.
Being able to give subarrays to a procedure and preventing buffer overruns everywhere, reducing screw-up scope everywhere is a superpower I didn't know I needed before starting writing proved parsers.
Yup, correct. What I meant above with array[Length(array)] is for the languages that don't have it. Let me be more clear.
C/C++ doesn't have custom array indexes and as such <array[std::size(array) - 1]> is returning the last element of said array.
Delphi has custom array indexes and as such, taking your example with defining an array in the form <example_array : array[3..7] of integer>, I would not get the last element in case of <example_array[Length(example_array) - 1]. In this case I would have 2 options. Option 1 would be to use <High> function as in <example_array[High(example_array)]> to access example_array[7] element. Delphi also has <Low> function so you can iterate through a custom defined array by using <for> keyword with the help of them. Option 2 would be to actually build my own helper (this is the most wanted case when you're dealing with multi-dimensional arrays that also have custom indexes) and I would have something like <example_array.FromLastIndex(0)> to access example_array[7] element.
As long as there exists a bijection between whatever you choose as an index and the natural numbers starting from 0 it is fine. (I.e. the range of valid indices must be a countable set)
In your example that bijection could be:
3 -> 0
4 -> 1
5 -> 2
6 -> 3
This works for vectors as well, so why not have a range from (0,0) to (5,5) to index into an array arr?
You could write the function that does the mapping manually: