On 5/31/16 4:59 PM, Dicebot wrote:
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" :(

If you want to use such "ranges", the compiler will not stop you. Just don't expect any help from Phobos.

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.

There's no requirement or need to prevent it. Just a) don't do it, or b) deal with the consequences.


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.

RedBlackTree with "a == b" will compile and operate. It just won't do much red-black-tree-like things.

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).

That's a little much. If you expect such things, you can construct them. There's no way for the functions to ascertain what your lambda is going to do (halting problem) and determine to cache or not based on 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".

Then it's not a bug? It's going to work just fine how you specified it. I just don't consider it a valid "range" for general purposes.

You can do this if you want caching:

only(0).map!(x => uniform(0, 10)).cache

-Steve

Reply via email to