Reference semantic ranges and algorithms (and std.random)

Johannes Pfau nospam at example.com
Thu Sep 20 03:47:21 PDT 2012


Am Thu, 20 Sep 2012 12:23:12 +0200
schrieb "monarch_dodra" <monarchdodra at gmail.com>:
> 
> That is a good point, I'd also make the "default" heap allocated, 
> but give a way to access a stack allocated payload.
> 
> Regarding the "developer mistake", the problem is that currently:
> "Misnstdrand a;"
> Will create a valid and seeded PRNG that is ready for use, so we 
> can't break that.

Well for by reference types we'd need intialization, so there's
probably no way not to break it. We'd probably have to do the
initialization check in release mode for some phobos releases.
But after some time it should be changed to a debug-only warning.

> 
> Arguably though, the argument holds for Mersenne twister, which 
> needs a function call to be (default) seeded.
> 
> HOWEVER I find that:
> auto a = MersenneTwister();  //Not seeded and invalid
> auto b = MersenneTwister(5); //Seeded and valid
> Is a confusing, especially since MersenneTwister provides 
> "seed()" to default seed.
> 
> I'd rather have:
> auto a = MersenneTwister();  //Not *yet* seeded: It will be done 
> on the fly...
> auto b = MersenneTwister(5); //Seeded and valid
> 
> But AGAIN, on the other hand, if you change back again to your 
> proposed stack allocated MersenneTwisterImpl:
> auto a = MersenneTwister();  //Not Seeded, but not assertable
> auto b = MersenneTwister(5); //Seeded and valid
> 
> It really feels like there is no perfect solution.
> 
> ********
> The truth is that I would have rather ALL prngs not have ANY 
> constructors, and that they ALL required an explicit seed: This 
> would be uniform, and not have any surprises.
> 
> OR
> 
> That creating a prng would seed it with the default seed if 
> nothing is specified, meaning that a prng is ALWAYS valid.
> 
> It feels like the current behavior is a bastardly hybrid...

That's what I did in std.digest. All Digests have a start() method,
even if it's not necessary for that specific Digest. It's probably a
good solution if you want a uniform interface for types which need
initialization and types which don't.

But there's also another, nice solution which should work: Introduce a
new makeRNG template function. This func checks if the RNG has a seed
function and calls it if available. Then you can do this for all RNGs:

auto rng = makeRNG!MersenneTwister();
auto rng = makeRNG!Misnstdrand();


More information about the Digitalmars-d mailing list