Live data from Hacker News

Always use [closed, open) intervals

fhur.me

61–70 of 169 posts

Re: Always use [closed, open) intervals

#61
I have recently been on the other side of this argument for specific case.

In our case we (users of our API) are to specify date ranges, representing a list of partitions. So we are not counting nights between dates, but rather a set of daily or hourly buckets.

Here (maybe even only here) I argue that inclusive ranges feel more intuitive.

I find it much more intuitive to represent the 1st 7 days of January as

['2022-01-01', '2022-01-07']

compared to

['2022-01-01', '2022-01-08').

Another very common example is to specify the last 7 days (incl 'today') in which case I find

[today().minusDays(6), today()]

to be a clearer representation than

['today().minusDays(6)', 'today().plusDays(1)')

Re: Always use [closed, open) intervals

#62
post #29

Half-open intervals are why I try as much as possible to stay away from languages that use 1-based indexing (Lua, Julia, Matlab, R, ...) - 1-based indexing lends itself to closed intervals because an array of N elements has [1,N] as its index range, whereas 0-based indexing lends itself to half-open intervals because an array of N elements has [0,N) as its index range. ------- However, I know of one case where closed…

I wonder if a lot of Lua's 1-indexed pain would be avoided by encouraging for-each style loops. Unless you need a specific sub range within an array, for-each will get you pretty far.

Re: Always use [closed, open) intervals

#63
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>

* * --

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 set is one-too-large: (560 - 554) == 6. So this too seems prone to off by one error.

[closed, open> and , the latter number isn't part of the array (560 is "one past the end), while in , 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.

Re: Always use [closed, open) intervals

#64

> Never, ever, ever use [closed, closed] intervals I’m not really a fan of “never,” or “always” rules, when it comes to programming. I’ve found it’s usually better to have a “make sure to justify deviations from” heuristics. I usually use [closed..open) ranges (as they are called in Swift), but sometimes, an inclusive range is a lot more appropriate, for expressing an operation (for example, I may express a range as…

I've moved away from this.

Advice is supposed to convey information simply and efficiently, and "asterisks" for every edge case just muddle it. Now my pet peeve has moved to folk wheedling about 100% accuracy in advice. ;-)

e.g.

Great advice:

    "Never run a red light"
vs

Technically-correct-but-will-never-be-read advice:

    "Don't run a red light, unless you're on a bicycle and you know that the intersesction you're at is on a weighted sensor that you're not going to set off. In which case, check your local laws on how to get through the intersection. Also, this likely applies to motorcycles. But not all motorcycles, so check your motorcycle's weight and cross-reference it to the weight sensors in your intersection (you'll need to contact your municipal engineering corps to get this). Also, one should look up for falling pianos at this point as well, just in case, because I can't say the word 'never'."

Re: Always use [closed, open) intervals

#65
post #62
post #29

Half-open intervals are why I try as much as possible to stay away from languages that use 1-based indexing (Lua, Julia, Matlab, R, ...) - 1-based indexing lends itself to closed intervals because an array of N elements has [1,N] as its index range, whereas 0-based indexing lends itself to half-open intervals because an array of N elements has [0,N) as its index range. ------- However, I know of one case where closed…

I wonder if a lot of Lua's 1-indexed pain would be avoided by encouraging for-each style loops. Unless you need a specific sub range within an array, for-each will get you pretty far.

That's a big thing with Julia actually. A lot of people first getting into it criticise it for its use of 1-based indexing (I'm not the biggest fan of it either tbh), but in reality, there are very few cases in which you actually directly interact with array indices at all. And even if you do, the idiomatic way to iterate over the indices of an array is to use the `indices`-function, which has the benefit of working with multidimensional arrays, or arrays that start with an index other than 1.

Re: Always use [closed, open) intervals

#67

I know Dijkstra's paper and it's short, good and should be read but this article is wrong in saying always . It feels like a newbie programmer came across a good thing then lost all proportion; use the right tool for the right job, as ever.

Fuck Dijkstra, his only argument was "this is ugly"

Re: Always use [closed, open) intervals

#68
post #36

Half-closed is generally good because it tends to reduce off-by-one errors. But this article overstates the case. Especially for floating-point, where the distinction between a The “splitting by time” section should probably just be removed, since it confuses the point and doesn’t add anything. The scenario doesn’t really make sense (if you wanted this you’d store the registration time and get the hour you’d be bette…

> Especially for floating-point, where the distinction between a I would argue that if your floating point code cares about < vs <= then you are probably making a mistake.

Re: Always use [closed, open) intervals

#70
post #61

I have recently been on the other side of this argument for specific case. In our case we (users of our API) are to specify date ranges, representing a list of partitions. So we are not counting nights between dates, but rather a set of daily or hourly buckets. Here (maybe even only here) I argue that inclusive ranges feel more intuitive. I find it much more intuitive to represent the 1st 7 days of January as ['2022-…

Your 1st 7 days still works with an open interval:

['2022-01-01', '2022-01-01' + days(7) )

Also, isn't this 6 days?

[today().minusDays(6), today()] --> ['2022-11-16', '2022-11-22']

To be fair, I'm considering these dates/times as singular points in time to the smallest resolution available in whatever time system is being used.

Post reply on HN