On Tuesday, 18 June 2013 at 09:32:35 UTC, Jonathan M Davis wrote:
On Tuesday, June 18, 2013 10:27:11 Joseph Rushton Wakeling
wrote:
On 06/18/2013 08:06 AM, Jonathan M Davis wrote:
> It would probably be a pretty easy sell though, since it
> can probably
> stay
> mostly the same aside from the struct -> class change
> (though at that
> point, we might as well take the opportunity to make sure
> that anything
> else that should be redesigned about it gets redesigned
> appropriately).
Yea, this is also my feeling, which is part of why I'm pushing
this concept
of "random ranges" -- I want to ensure that the related issues
are properly
understood and discussed and some well-thought-out design
patterns are
prepared in order to ensure good and statistically reliable
functionality
in std.random2.
One small note -- I'd have thought that a struct with an
internal
pointer-to-payload (allocated using manual memory management,
not GC) would
have been a superior design for pseudo-random number
generators compared to
making them final classes. The latter is just the easiest
thing to do for
simple tests of PRNG-as-reference-type.
An internal payload might make more sense, but it probably
needs to be done in
a way that it can be controlled (which may require custom
allocators), because
even allocating with malloc all the time might be a problem for
the guys who
are really picky about memory stuff - though maybe that level
of customization
could be added later. I don't know. I also don't work in that
kind of
environment, so I don't know exactly what such programmers find
acceptable.
- Jonathan M Davis
Memory wise, classes or pointer to payload will both have a
memory allocation cost anyways. classes will be on the GC,
whereas structs *may* use malloc + ref count.
The advantage of classes is that you can default initialize them,
which is a real + given that some random ranges may need priming.
(or we could bring up yet again the subject of allowing structs
to have explicitly callable constructors with no arguments).
What I remember, is that there were some people who did numerics
that didn't want to have reference types, because of the overhead
to access the payload. They *really* wanted to be able to declare
their types on stack.
What I did find though is that if you implement all of the PRNGs
as value types, you can then easily wrap them all inside a
reference types or class. This:
1: Makes implementation easier
2: Leaves a door open for users that want explicitly value types
(at their own responsibility).
The last issue is input vs forward. IMO, PRNG's should be input
by *default*, and forward (when possible) on demand. Making a
PRNG forward by default means you can't prevent an algorithm from
saving your range. That means that *even* if you have a reference
type, you could still have duplicate series. In the above example
with dual call to "array", one can *hope* to have two different
ranges... but there is nothing preventing array from calling
"save" just to troll the user. fill does (used to) do it :D
I was also able to implement this pretty easily: Just give the
saveable ranges the "dup" primitive. Users of the PRNG can then
explicitly dup if they want to very safely and explicitly. If
they really want a ForwardPRNG, then a simple adaptor that adds
save in terms of dup is provided.