<div>Well, my main motivation in the work over the last few days was to fix correctness problems in System.Random (and performance as secondary).  I think this matters whether or not it is shipped only for Haskell 98 or not.  I&#39;ve been focused mainly on the Random instances.  Does anyone know good points of comparison for these?  I&#39;ve seen lots of PRNGs on Hackage but not lots of code that maps that randomness onto the usual types (Double, Integer, Char, etc).</div>

<div><br></div><div>My hope is to improve random to the point that it provides a good, simple default library.  From a pedagogic perspective I imagine many new users want randomness but don&#39;t want to scour hackage and learn the more complex interfaces.  So as long as &#39;random&#39; is a clear default I am happy, whether or not it&#39;s part of the GHC distro or Haskell Platform.</div>

<div><br></div><div>In my mind a good default implementation has decent-to-good performance, generates uniform distributions (#5278, #5280), and has statistically sound splitting.  If we had a those three things maybe there would not have been as much motivation to provide new RNGs!</div>

<div><br></div><div><b>Re &quot;nextBits&quot;:</b></div><div>Thomas, could we flesh out the performance argument for bulk random bit generation?  It seems to me that if we do a good enough job with Data.Bits that an interface that produces a word at a time is not that bad in terms of throughput.  (On the bit producer side, producing in bulk and then doling out word-at-a-time seemed to work pretty well for me when I was testing it in intel-aes.)  The biggest problem I see is that a kind of redundant buffering could occur if both the bit-producer and the bit-consumer want bulk randomness but have to communicate it through individual words.</div>

<div>   That said, if bytestring dependency is ok -- why not?  It then becomes a backwards-compatible change that may open an extra opportunity to some RNGs.</div><div><br></div><div><b>Re &quot;newGen&quot;:</b></div><div>

I like Thomas&#39;s interface and I&#39;ve been thinking about the &quot;newGen&quot; issue as well:</div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; ">   newGen :: ByteString -&gt; g</span></div>

<div>Here ByteString does seem most appropriate, anything else -- Int or [Int] -- seems unsatisfactory.</div><div><br></div><div>Just for arguments sake I&#39;d like to reexamine the &quot;SplittableGen&quot; topic in light of &quot;newGen&quot;:</div>

<div>   <a href="http://www.haskell.org/pipermail/libraries/2010-September/014252.html">http://www.haskell.org/pipermail/libraries/2010-September/014252.html</a></div><div>It seems that with newGen we could provide a default implementation of split and keep it in RandomGen.  Yes, it would be poor.  But it would mean that things like Mersenne don&#39;t have to throw an error.  Further, if stdGen were to, say, provide cryptographically strong RNG with sound splitting -- would the quality of the default split be as much of a concern?  Someone who chooses anything other than stdGen in that case would have to have a good reason for doing so, and I think can be saddled with the consequences.</div>

<div><br></div><div>Adding newGen instead of subtracting split would not be Haskell-98 backwards compatible.  However, it would create a <b>different</b> kind of breakage than subtracting split.  Subtracting split breaks the client code, whereas adding newGen just breaks the instances of RandomGen (hopefully few).</div>

<div><br></div><div>Don&#39;t we want to be pushing splittable tree RNG <b>more</b> in the future?  GHC for parallelism, right!?  Let me give an example of the feature&#39;s value -- the Cilk  folks are making significant changes to their runtime just to get deterministic parallel RNG:</div>

<div>    <a href="http://groups.csail.mit.edu/sct/wiki/index.php?title=Other_Projects#Deterministic_Parallel_Random-Number_Generation">http://groups.csail.mit.edu/sct/wiki/index.php?title=Other_Projects#Deterministic_Parallel_Random-Number_Generation</a></div>

<div><br></div><div>My feeling is that if we could get the best of what&#39;s out there into one library with a simple interface and made it default that it would have a positive impact and avoid unnecessary balkanization and do-it-yourself in the random number department.  In order to accomplish this maybe we would need two stdGens.  One maximally fast and one maximally sound --  perhaps Mersenne Twister and crypto-based splittable RNG?</div>

<div><br></div><div>By the way, perhaps that &quot;genBits&quot; method should probably be rename &quot;genRangeBits&quot;?</div><div><br></div><div>  -Ryan</div><br><br><div class="gmail_quote">On Tue, Jun 28, 2011 at 6:01 PM, Thomas DuBuisson <span dir="ltr">&lt;<a href="mailto:thomas.dubuisson@gmail.com">thomas.dubuisson@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">Ryan Newton &lt;<a href="mailto:rrnewton@gmail.com">rrnewton@gmail.com</a>&gt; wrote:<br>
&gt; There implementation has two major pieces:<br>
&gt;     (1) Sources of random bits (class RandomGen)<br>
&gt;     (2) Instances of class Random that map use random bits to create Haskell<br>
&gt; types<br>
<br>
</div>I&#39;d say there are three pieces, initial entropy (clock, external seed,<br>
system crypto random generator), deterministic generator interface<br>
(PRNG, the RandomGen class), and the instances of that class.<br>
<br>
I tried to answer the first item in System.Crypto.Random.  The &#39;random&#39; package<br>
never really had an answer for entropy and I&#39;m not sure what the<br>
community thinks about that.  Perhaps answering this problem in slightly<br>
obscure packages is OK.<br>
<div class="im"><br>
&gt; The issue is<br>
&gt; that the legacy RandomGen API isn&#39;t very good at generating random bits.<br>
<br>
</div>Agreed.  This is why CryptoRandomGen uses ByteString (so we can<br>
generate any number of BYTES of random values).<br>
<br>
As I tried to argue when I make RandomGen more polymorphic, this is an<br>
issue with hardcoding the type as Int.  Unfortunately, people didn&#39;t<br>
accept that alteration and I feel continuing to generating Int while<br>
allowing devs to discover the amount of entropy isn&#39;t taking things<br>
far enough.<br>
<div class="im"><br>
&gt; I&#39;d also be happy to hear other proposals for API changes and additions.<br>
<br>
</div>As I say below, I don&#39;t understand why we can&#39;t use ByteString.  There<br>
are (or should be) rather fast decodings of all the popular primitive<br>
types from bytestrings, so this takes care of our polymorphism issue.<br>
<br>
I accept that, unlike the CryptoRandomGen, we don&#39;t want an explicit<br>
failure for RandomGen.  But how about a common interface for<br>
instantiating generators (&#39;newGen&#39;)?  Is there a reason not to have that?<br>
<br>
--- CODE ---<br>
class RandomGen g where<br>
    next :: g -&gt; (Int, g)<br>
    nextBits :: g -&gt; BitLength -&gt; (ByteString, g)<br>
    genBits :: g -&gt; Int<br>
    newGen :: ByteString -&gt; g<br>
--- END CODE ---<br>
<br>
Also, perhaps we could still have an explicit reseed?<br>
<br>
--- CODE ---<br>
class Reseedable g where<br>
    reseed :: g -&gt; Bytestring -&gt; g<br>
--- END CODE ---<br>
<br>
I&#39;ll stop here before I entirely recreate CryptoRandomGen, but without<br>
the explicit errors and in more classes (the next step would be a method<br>
for querying how much entropy is needed for instantiation).<br>
<div class="im"><br>
&gt;  System.Random can&#39;t depend on bytestring, so I doubt we want block RNG in<br>
&gt; the RandomGen class.<br>
<br>
</div>Why can&#39;t it?  System.Ranomd isn&#39;t part of H2010 and H98 already needs<br>
its own random module.<br>
<br>
I&#39;ll try to make time to review the code, you&#39;ll hear if I do.<br>
<br>
Cheers,<br>
<font color="#888888">Thomas<br>
</font></blockquote></div><br>