In Mathematics, especially Real Analysis and Topology, the use of open and closed intervals is endemic. The open interval \((a,b)\) is the interval \(a < x < b\) while the closed interval \([a,b]\) includes the endpoints: \(a \le x \le b\). There is also the notion of a closed/open interval \([a,b)\): \(a \le x < b\).
You’ve probably noticed that operators in most programming languages operate on closed/open intervals. A common example is the sub string operator, substr
say, found in many languages. They all work pretty much the same. The function substr(a,b)
specifies the string of bytes starting at byte \(a\) up to but not including byte \(b\). If you’re like me, you’ve probably occasionally found this annoying. If you want bytes 2, 3, and 4, it seems natural to write substr(2,4)
rather than substr(2,5)
.
Fernando Hurtado Cardenas has a post that explains this seeming anomaly. Although using a closed interval seems more logical and has a nice symmetry, it often leads to unexpected edge cases and brittle code with a lot of special cases. The worst thing is that the closed interval works most of the time. It’s those easy to overlook corner cases that trip you up. Cardenas discusses some of those edge cases and offers a pretty good argument that the annoying closed/open interval is the right thing. Take a look at his post. If nothing else, you’ll feel better about those operators using closed/open intervals.