I guess the majority of the people are not like this, but arguments like "just look at it how strange it looks" don't do it for me, because it looks natural, and the other way looks complicated.
If I am working with closed ranges, [i:i-1] looks like the list [i, i-1]. Like [5:2] would be [5, 4, 3, 2].
With [b+1:c] I would feel like I needed to insert a check to ensure b+1 <= c. With the closed ranges the invariant "left is <= right" is maintained automatically. Though I guess it doesn't matter so much if you accept any list with left > right as the empty list.
The issues with compositionality become even more noticeable with floats. Then you would need [a:b] + [b + minimum_float : c], or something like that.
1 <= a <= N -- N = length, no delta
0 <= a < N -- N = length, no delta
You only calculate the length when dealing with other than 0- or 1-based ranges. There, the inclusive-exclusive convention is very handy as you point out. So if we're fixing the initial offset at either 0 or 1, then use the appropriate convention for that offset. If we let the initial offset float, then the inclusive-exclusive makes sense.E.g. in Java, a typical example is that OutputStream has the following two methods, where the first can delegate to the second, and the second (which write the specified subrange of the array) can easily calculate the number of bytes to write:
int write(byte[] bytes)
{
return write(bytes, 0, bytes.length);
}
int write(byte[] bytes, int start, int end)
{
int length = end - start;
...
}> If we let the initial offset float, then the inclusive-exclusive makes sense.
But you replied to someone using inclusive-inclusive for 1-based arrays and complained about the delta not matching the length. Which is a nonsensical complaint, you have the length already why would you need to calculate anything?