Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.


Closed 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).


For 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.


I'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.


cannot?


Then 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.


Why 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.


It 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;
      ...
  }


I 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?


In 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: