§ How to reason with half-open intervals
I've always found code that uses half-open intervals far harder to write
than using closed intervals. For example, when performing string processing,
I prefer to write closed over halfopen since I find it easier
to think about:
void closed(int begin, int end, char *c) {
for(int i = begin; i <= end; ++i) {... }
}
void open(int begin, int len, char *c) {
for(int i = begin; i < begin + len; ++i) { ... }
}
However, I realised that by changing how I think about this to:
void open(int begin, int len, char *c) {
for(int i = begin; i != begin + len; ++i)
}
It somehow made it way easier to grok.
- I had problems with
< since I would mentally shift from i < begin + len to i <= begin + len - 1. Making this move would then make all other reasoning harder, since I had keep switching between the < and <= point of view.
- On the other hand, when using
i != begin + len, there was a single location to focus on: the point begin + len, and what happens when i reaches it.
Of course, this is old had to anyone who performs loop optimisatison: LLVM
internally converts most comparisons into the a != b form, because it's
easier to analyse. It took me this long it's easier for me to think
in this viewpoint as well.