On Tuesday, 31 May 2016 at 18:11:34 UTC, Steven Schveighoffer
wrote:
1) Current definition of input range (most importantly, the
fact `front`
has to be @property-like) implies `front` to always return the
same
result until `popFront` is called.
Regardless of property-like or not, this should be the case.
Otherwise, popFront makes no sense.
Except it isn't in many cases you call "bugs" :(
2) For ranges that call predicates on elements to evaluate
next element
this can only be achieved by caching - predicates are never
required to
be pure.
Or, by not returning different things from your predicate.
It is perfectly legal for predicate to be non-pure and that would
be hugely annoying if anyone decided to prohibit it. Also even
pure predicates may be simply very expensive to evaluate which
can make `front` a silent pessimization.
This is like saying RedBlackTree is broken when I give it a
predicate of "a == b".
RBL at least makes certain demands about valid predicate can be.
This is not case for ranges in general.
3) But caching is sub-optimal performance wise and thus bunch
of Phobos
algorithms violate `front` consistency / cheapness expectation
evaluating predicates each time it is called (liked map).
I don't think anything defensively caches front in case the
next call to front is different, unless that's specifically the
reason for the range.
And that makes input ranges violate implication #1 (front
stability) casually to the point it can't be relied at all and
one has to always make sure it is only evaluated once (make stack
local copy or something like that).
I think we should be aware that the range API doesn't prevent
bugs of all kinds. There's only so much analysis the compiler
can do.
This is a totally valid code I want to actually work and not be
discarded as "bug".