4 ms·
It could just as easily be 1 ≤ i ≤ N and then I wouldn't have to remember that the lower bound is inclusive and the upper exclusive.
by intrepidhero 4y ago
It could just as easily be 1 ≤ i ≤ N and then I wouldn't have to remember that the lower bound is inclusive and the upper exclusive.
- layer8 4y agoThen the delta of both bounds (N – 1) wouldn’t equal the length of the range (N). The inclusive-exclusive convention is used in order for `end = start + length` to hold.
- Jtsummers 4y agoWhy does that matter when the starting point is 1? In that case, you don't need the delta because you have the length already. In the case of a 0-based range you also don't need the delta, though you will want to use the inclusive-exclusive convention so that you get the length "for free". 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.
- layer8 4y agoIt matters whenever you need to process a proper subrange of an array, and that shouldn’t be different from when the subrange happens to be the whole range. It’s simpler if the same convention is used in all cases. 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; ... }
- Jtsummers 4y agoI addressed that: > 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?
- layer8 4y agoIn case of the subrange you don’t have the length (or you conversely have the length but not the upper bound), and you don’t want to use different conventions based on whether you process the subrange or the whole range. I’m not sure how I can make it clearer.
- thomasahle 4y agoClosed ranges (with both ends inclusive) are super annoying to work with. You can represent the empty range (unless you are willing to do [i : i-1]), and they don't compose like half open ones: [a : b) + [b : c) = [a : c).
- elikoga 4y agocannot?
- bmacho 4y agoFor some reason I am thinking in the terms of closed ranges if not specified otherwise/doing it for myself. [i:i-1] is how i think of empty ranges, and [i:i] if I want to capture the element i with a range. Also [a:b] + [b+1:c] corresponds more what I want, than [a:b) + [b:c). 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.
- thomasahle 4y agoI'm curious if you would also accept [i:i-2] as a an empty list, or in general anything where the right side is smaller than the left? 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.