On Friday, 27 November 2015 at 12:06:02 UTC, Joseph Rushton Wakeling wrote:
On Friday, 27 November 2015 at 11:57:37 UTC, Jonathan M Davis wrote:
Well, you can have a pure input range which is lazy, but what you can't do is wrap it in another lazy range. A prime example would be something like

    auto first5 = range.take(5);
    range.popFront();
    range.popFront();
// first5 now refers to elements 2 through 6 rather than 0 through 4

Hmm well, I think it depends on how you approach the question of what is "correct" there. If range is a RNG then that behaviour could arguably be OK; the 5 numbers extracted from the RNG are evaluated as you consume them, and that's all right.

Well, if you're dealing with a pseudo-random generator with a specific seed, I'm not sure that it's okay, though obviously for a fully random number generator, it wouldn't matter. The real problem is that this affects _any_ input range that's a reference type, not just random number generators, and the order very much matters for most range types. The problem can be fixed for forward ranges via save, but not for pure input ranges. And it's even worse with pure input ranges if they're not required to be full-on reference types, since then who knows what the state of the range is after it's copied to be passed into take. Right now, generic code can't use any range that's passed to take (or any function like it) after it's been passed in, because it's undefined behavior given the varying, possible semantics when copying a range, though calling save first obviously gets around that problem for forward ranges. But it's pretty certain that there's lots of code out there that actually depends on that undefined behavior acting like it does with dynamic arrays, because that's what most ranges do.

This is where I'm wishing I knew Haskell better, because I'm increasingly suspecting that InputRanges ought to be thought of in much the same way as Haskell considers IO.

Possibly, but because almost everything in Haskell is both functional and lazy, you don't really get the problem of popFront being called after the call to take.

- Jonathan M Davis

Reply via email to