New Lagged Fib. PRNG gen and random2.d

Joseph Rushton Wakeling joseph.wakeling at webdrake.net
Mon Aug 26 08:55:42 PDT 2013


On 26/08/13 17:26, monarch_dodra wrote:
> One more thing. One of the ways I see it (specifically for LF): We can add
> auto-seed later if we decide it was a bad idea to not have it. The opposite
> isn't possible.

Yes.  I feel similar about the question of whether or not pseudo-random RNGs 
should have .save methods or not.  I can see use-cases, but better to avoid at 
first (while as you have suggested implementing .dup) and then, if it turns out 
that was a bad idea, add them.

> Another option I had thought of, was to make the value-types Payloads as public,
> with *massive* "do not use signs". *We* then provide simple and generic (and
> pure/nothrow) GC-based wrappers.

Related to this, I was thinking about how my RandomGenerator implements the 
isUniformRandom property (it aliases to the corresponding property of the 
underlying random engine/payload).

Now, if you suppose that the payloads _don't_ define isUniformRandom but define, 
say, isRandomPayload or isRandomEngine, and then in the RandomGenerator wrapper 
you have,

     alias isUniformRandom = Payload.isRandomPayload;

... then the isUniformRNG check of other functions WON'T WORK with the raw 
Payloads.  So you have a static safety check in place that will plain stop users 
doing stupid stuff.

That is beneficial, because it means that a user can for example make use of the 
Payload definition to define a new RNG of existing type but with different 
configuration (e.g. Lagged Fib with different parameter values).

>  From there, if, for whatever reason, a user needs malloc allocation, or heck,
> static allocation, he still has an "underhand" access to the payload
> implementation, but lifecycle management remains *his* responsibility.
>
> I think: Simple and safe by default, with the possibility for extension.

Yes, if we handle isUniformRandom like this.

> Again, for now, I think this is implementation detail. That said, I don't buy
> much into the typo argument. In particular, this is something that gets copy
> pasted only once, so we should be relatively safe.
>
> One of the arguments in favor of "internal" mixins is that of extension: For
> example, laggedFib has a very real reason to implement popFrontN, as it can
> potentially pop thousands of elements at once in o(1). "Internal" mixin makes it
> easy to extend a PRNG's capabilities past that of the "lowest common
> denominator". With a "alias Random = RandomGenerator!RandomPayload", you are
> really limited to whatever RandomGenerator wrapped.

Fair enough, but I think there are other ways of handling that, e.g. via 
opDispatch.  We ought to be able to make sure that _all_ public methods and 
properties of the payload get forwarded.

And -- devil's advocate -- how many different extensions are there likely to be 
in practice?  Is it not the case that we can anticipate them and make sure they 
are in the wrapper?  How many operations can one reasonably expect from a RNG?

> Honestly, it might just be the simplest thing to do. For one, it would elegantly
> solve the "must be seeded" issue (allocation is initialization). It *guarantees*
> Reference semantics. Finally, the (supposed) overhead should be inexistant
> compared to the compelxity of a PRNG.
>
> The option of allowing "public Payload" definitions could still leave an open
> door for those that need PRNG's, but don't use the GC (think vidjagames).

I would quite like to have Andrei and Walter's input on the struct vs. class 
aspect, and Phobos design style.

One thought about "public payload" and wrappers: it ought to be possible to 
design things so that a RandomGenerator wrapper can be initialized by passing a 
pointer-to-payload instead of a seed, which obviates the need for internal 
allocation.  And we can use that approach for rndGen() so that the default RNG 
instance doesn't require GC.


More information about the Digitalmars-d mailing list