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

Ehh, this post misses the important tidbid.

You should keep your code consistent across your organization, so that a large number of programmers knows how your code works. You should have a "default writing style", and the "default writing style" should be used unless you have very, very, very good reasons to avoid it. (And an errant +1 or -1 here and there isn't a good enough reason to switch).

There are four styles of intervals. Lets say you want to represent a loop of 5 iterations numbered [555, 556, 557, 558, 559]. You've got:

* [closed, closed] -- [555, 559]

* [closed, open> -- [555, 560>

* <open, closed] -- <554, 559]

* <open, open> -- <554, 560>

There's not much difference to any of these four. As long as you pick a singular choice, get comfortable with its quirks, and make it consistent across your organization, you get benefits.

The main reason we do [closed, open> is because Dijkstra (father of structured programming back in the 1960s), argued to use [closed, open>, when presented with all these options. (and argued for zero-indexed as well).

The "[closed, closed]" set is one-too-small (559 - 555 == 4), so you need to add +1 to the representation.

The <open, open> set is one-too-large: (560 - 554) == 6. So this too seems prone to off by one error.

[closed, open> and <open, closed] are both the correct size of 5 when you subtract, but both "includes" a number that doesn't exist. In [closed, open>, the latter number isn't part of the array (560 is "one past the end), while in <open, closed>, the first number isn't part of the array.

Make that what you will of it. [closed, open> became a programmer convention because of these reasons. The important bit is to know all the quirks / off by one errors associated with this representation.



Once you go beyond integers, using [closed, open) or (open, closed] becomes more important, because otherwise you cannot represent adjacent intervals.


The empty interval problem applies to integers too: [15,15) and (15,15] are empty, [x,y] is not for any x and y.


for any x>y [x,y] is empty, i.e. [15,14]

an interval is a set and sets can be empty [x,y) = { z where x<=z and z<y }


Dijkstra is a smooth talker and sometimes he's able to convince people that an argument is settled even when it is not... Here, he conveniently ignores examples that are better for [closed,closed], such as iterating backwards over the range. That is more annoying for [closed,open) because it turns into the abhorent (open,closed].

An argument I prefer is this: [closed,closed] is better for representing an index into the range while 0-based with [closed,open) is better for offsets. They are not the same, as C would have you believe, and there are situations where behaves nicer than the other.


> That is more annoying for [closed,open) because it turns into the abhorent (open,closed].

What's wrong with (open, closed] ?? Especially if you're going backwards?

    for(int i=559; i>554; i--){
        //do stuff with i
    }
Perhaps the most important reason to do zero-indexed + [closed,open> and <open, closed] is because these are the defaults the C / C++ / Java for loops assume you're doing.

Its all non-intuitive because humans are really bad with off-by-one errors.

------

EDIT: I guess familiarity with [closed, closed] is somewhat important, because other programmers like the form. The pattern here is: for(int i=start_closed; i<=end_closed; i++), if anyone's curious.


The problem with that example is that you had to ±1 both of the ends of the original range. That is, you started with [555,560) and had to rewrite it to (554,559] for the reverse loop.


No one really wants [x, y). That want [0,y) or [x,x+y) because y is the length of the interval.

So no one wants (y,x] when going backwards, because x<>0 there.


I remember at the time when C++ ranges were getting standardized there was a talk about an alternative replacement for iterators: splitting them into things that point at elements and between them. That solved the reversal / backward iteration problem rather neatly, although IIRC there wasn’t always a clear choice of which kind of thing should now be returned in place of a single iterator.

(Of course, that doesn’t help at all if you’re using raw indices, but then again, people used to describe screen coordinates as pointing between “little square” pixels rather than at sample locations back in the days of the original Macintosh and 16-bit Windows.)


> You should keep your code consistent across your organization, so that a large number of programmers knows how your code works.

I would argue that for this reason it's not just important to have a consistent style across your organization, but also to use the convention that your slice of the industry has settled on, which for most companies is [closed, open). If there's no particularly good reason to use one over another, why add extra overhead to the onboarding process?


Here's one quirk I once encountered in the real world: a route represented by a sequence of distance, elapsed-time tuples. You can calculate the average speed to each waypoint - except for the zero-time waypoint, if it is included in the list.

I guess we normally think of intervals starting at some point and extending until the next interval starts, but that is not necessarily the most useful or 'natural' way of representing the situation.


> I guess we normally think of intervals starting at some point and extending until the next interval starts

Given how bad people are with the fencepost problem in practice... (Each pair of fenceposts covers 1-yard (or meter) of distance. How many meters does 100 fenceposts cover?), I'd say humans normally don't think of intervals very much.

Instead, we programmers have to think of intervals way more than other humans. So we need to develop systems and shortcuts for our brain to handle these cases quickly, concisely, and then move onto the next problem immediately.

-------

It doesn't matter what style you use, as long as you're fast and precise with that style (and as long as your coworkers are also fast and precise with the style).




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: