On Friday, 21 September 2012 at 19:47:16 UTC, Jonathan M Davis wrote:
On Friday, September 21, 2012 15:20:49 monarch_dodra wrote:
#3
The only thing I'm having an issue with is "save". IMO, it is
exceptionally dangerous to have a PRNG be a ForwardRange: It
should only be saved if you have a damn good reason to do so. You
can still "dup" if you want (manually) (if you think that is
smart), but I don't think it should answer true to
"isForwardRange".

It is _very_ crippling to a range to not be a forward range. There's lots of stuff that requires it. And I really don't see what the problem is. _Maybe_ it's okay for them to be input ranges and not forward ranges, but in general, I think that we need to be _very_ careful about doing that. It can be really,
really annoying when a range is not a forward range.

I know it is crippling, but that is kind of the entire point: If somebody wants to read the same numbers trough twice, he'd better have a damn good reason. For example, *even* with reference ranges:

----
auto rng = SomeReferenceForwardRange();
auto a = new int[](10);
auto b = new int[](10);
a.fill(rng);
b.fill(rng);
----

This will fill a and b with the *same* numbers (!), even though rng is a reference range (!) Arguably, the bug is in fill (and has since been fixed), but the point is that by the time you notice it, who knows how long you've debugged? And who knows which *other* algorithms will break your prnd?

Had the rng been only InputRange, the compilation would have raised an error. And the work around is also easy. Safety first, right?

It might not be worth deprecating *now*, but I do think it is a latent danger.

PS: In all of random, there is not one single use case for having a ForwardPrng. Just saying.

You just don't know what an algorithm will do under the hood if
it finds out the range is saveable. In particular, save can be
non-trivial and expensive...

It shouldn't be. It's a copy, and copy's are not supposed to be expensive. We've discussed this before with regards to postlbit constructors. Certainly, beyond the extra cost of having to new things up in some cases, they should be
relatively cheap.

The copy of the reference is designed to be cheap (and is), yes (we've discussed this).

However, when you save, you have to duplicate the payload, and even considering that there is no postblit cost, you have strictly no control over its size:

LCG: 1 Int
XORShift: 5 Ints
MersenneTwister: 397 Ints
LaggedFib: (607 to 44497) ulongs or doubles

Not the end of the world, but not trivially cheap either.

QUESTION:
If I (were to) deprecate "save", how would that work with the
range traits type? If a range has "save", but it is deprecated,
does it answer true to isForwardRange?

You'd have to test it. It might depend on whether -d is used, but it could
easily be that it'll be true as long as save exists.

- Jonathan M Davis

I just tested it btw:
without -d: isForwardRange: false
with    -d: isForwardRange: true

It is kind of the logical behavior actually.

Reply via email to