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