range.save
Jonathan M Davis via Digitalmars-d
digitalmars-d at puremagic.com
Fri Nov 27 04:16:32 PST 2015
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
More information about the Digitalmars-d
mailing list