§ 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) { //easier
  for(int i = begin; i <= end; ++i) {... }
}

void open(int begin, int len, char *c) { //harder
  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) { //harder
  for(int i = begin; i != begin + len; ++i)
}

It somehow made it way easier to grok.


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.