Pascal and derivatives (Delphi) indexes from 1, and it has pluses and minuses.
For loops are more natural when indexing from one; for loops in most languages specify inclusive ranges, but indexed containers typically advertise their, rather than their maximum index. You don't notice this much in C and derived languages because the for loop in those languages is more flexible (and more open to abuse).
More concretely, this is a very common idiom in Delphi when dealing with 0-based containers:
for i := 0 to list.Count - 1 do
The '- 1' on the end is ugly. What's needed is a way of expressing a half-closed interval, but that's not common in programming languages (despite it being a great aid to correctly expressing many algorithms concisely).
Let's say you want to insert into the middle of an array, at x, with count elements (and presumed free space at the end). You need to move all the elements from x to the end up one. Let's suppose you have a move(array, fromIndex, toIndex, count) function that can do that. In 0-based languages:
move(array, x, x + 1, count - x)
But you need to adjust it for 1-based languages:
move(array, x, x + 1, count - x + 1)
However, you can mitigate it by changing how the move() function takes its parameters:
move(array, startIndex, endIndex, newIndex)
move(array, x, count, x + 1)
If everyone is consistent, and APIs are designed with 1-based indexing in mind, most of the issues go away. It's when there are mixed styles that things get painful.
>What's needed is a way of expressing a half-closed interval, but that's not common in programming languages (despite it being a great aid to correctly expressing many algorithms concisely).
A slightly lesser known construction in Ruby, the ... Range operator does this.
For loops are more natural when indexing from one; for loops in most languages specify inclusive ranges, but indexed containers typically advertise their, rather than their maximum index. You don't notice this much in C and derived languages because the for loop in those languages is more flexible (and more open to abuse).
More concretely, this is a very common idiom in Delphi when dealing with 0-based containers:
The '- 1' on the end is ugly. What's needed is a way of expressing a half-closed interval, but that's not common in programming languages (despite it being a great aid to correctly expressing many algorithms concisely).Let's say you want to insert into the middle of an array, at x, with count elements (and presumed free space at the end). You need to move all the elements from x to the end up one. Let's suppose you have a move(array, fromIndex, toIndex, count) function that can do that. In 0-based languages:
But you need to adjust it for 1-based languages: However, you can mitigate it by changing how the move() function takes its parameters: If everyone is consistent, and APIs are designed with 1-based indexing in mind, most of the issues go away. It's when there are mixed styles that things get painful.