On Wednesday, November 23, 2016 14:02:36 Joseph Rushton Wakeling via Digitalmars-d wrote: > On Wednesday, 23 November 2016 at 13:56:27 UTC, Andrei > > Alexandrescu wrote: > > Well I do see another small problem with > > https://github.com/libmir/mir-random/blob/master/source/random/algorithm > > .d#L19. It creates the first value eagerly upon construction. That's > > just a bit awkward. It's not the first time I'm seeing this issue, and > > to be honest am a bit bummed about it. It's a consequence of all ranges > > needing to buffer at least one element. -- Andrei > Yea, this touches on one of my more general concerns related to > ranges, randomness and laziness. Part of the trouble is we don't > have a really good general design for how to implement _truly_ > lazy ranges, where the value of `front` is not determined until > the point where you first access it. > > This has particular relevance to e.g. RandomSample and > RandomCover.
It's quite feasible if you don't calculate front until it's called or popFront is called, and then you cache the result so that subsequent calls to front prior to the call to popFront return the same result, but it creates additional overhead, because then every call to front and popFront has to check whether the value has been calculated yet. And if every range in the chain of ranges has to do that, then that additional overhead is going to add up. In general, it's just cleaner to either calculate front on every call to front (which doesn't make sense in the case of random number generators) or to calculate the first front upon construction and be done with it. And I think that the general consensus has been that calculating front in the constructor and popFront and caching works better than calculating it on every call to front, but that doesn't always work (e.g. map), and that caching does cause issues occasionally. - Jonathan M Davis