I've always been curious around the design choice of ranges to make front and popFront separate functions, instead of having popFront return the front. I suppose it is useful sometimes to be able to access front multiple times without having to save it temporarily (can't think of a specific example though).

But sometimes doing popFront requires doing the same work as front. For example, for strings and autodecoding, both front and popFront need to determine the length of the next code point. Now for utf-8 that is still managable, but I'm making a tokenizer range for a programming language. Most of the logic in `front` needs to be duplicated for `popFront`! (and `empty` as well)

So I often end up with designs like:
```
struct Range
{
  string source;
  bool empty;
  Token front;
  this(string source) {
    this.source = source;
    popFront();
  }

  void popFront() {
    // *complicated logic*
    front = result;
  }
}
```

This increases the size of the Range struct, and makes the range one element eager. If the first token is invalid, and I use Exceptions, then merely constructing the range will immediately throw an Exception. I recall reading that constructors throwing exceptions are problematic, but I don't have any experience with that. So maybe I should add a try-catch in the constructor, and rethrow the Exception upon the first 'front' call? That feels hacky.

This is not a dealbreaker, I'm just curious on your tips and opinions regarding this.

Reply via email to