range.save

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Fri Nov 27 03:57:35 PST 2015


On Friday, 27 November 2015 at 11:45:38 UTC, Joseph Rushton 
Wakeling wrote:
> On Friday, 27 November 2015 at 11:31:14 UTC, Jonathan M Davis 
> wrote:
>> Another piece of this puzzle to consider is that unless a 
>> range is a value type (or at least acts like a value type as 
>> long as you don't mutate its elements) or has save called on 
>> it, then it fundamentally doesn't work with lazy ranges. So, 
>> at minimum, we need to consider making it so that lazy ranges 
>> require forward ranges (and then, assuming that we continue to 
>> have save, the lazy ranges need to always call save on the 
>> range that they're given).
>
> Ah, interesting you should bring that up, as it's exactly the 
> challenge of doing random number generation via a range 
> interface ;-)
>
> I'm looking at this problem from a slightly different angle, 
> which is that for a non-deterministic range (which is a subset 
> of possible InputRanges) to be lazy, it matters that the value 
> of .front is not evaluated until the first call to .front; and 
> this "not yet determined" property needs to be restored after 
> .popFront() is called.
>
> Basically, you require _true_ laziness rather than the kind of 
> pseudo-laziness that most Phobos ranges display, where the 
> initial value of .front is determined in the constructor, and 
> .popFront() determines the next value of .front "eagerly".
>
> (N.B. "Non-deterministic" here includes 
> pseudo-non-deterministic ranges, such as pseudo-RNGs.)

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

Either take needs to actually get a separate copy of the range 
(i.e. use save), or the range can't be used after take has been 
called. So, wrapping the range in a lazy range does still work on 
some level - but only as long as you don't use the range for 
anything else other than through that lazy range, and I don't 
know of any way to restrict that except by either disallowing 
pure input ranges with lazy range wrappers (which is arguably 
over restrictive) or by simply telling people not to use a pure 
input range after passing it to a lazy range (which is obviously 
error-prone, because it's not enforced in any way).

Whether the original range was lazy or not doesn't really matter. 
It's the fact that it's not a value type that screws things.

- Jonathan M Davis


More information about the Digitalmars-d mailing list