<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
    "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xml:lang="en">
<head><meta http-equiv="Content-type" content="application/xhtml+xml;charset=utf-8" /><title>std::rand replacement, revision 3</title></head>
<body><!-- maruku -o randint.html randint.md --><style type='text/css'>
pre code { display: block; margin-left: 2em; }
div { display: block; margin-left: 2em; }
ins { text-decoration: none; font-weight: bold; background-color: #A0FFA0 }
del { text-decoration: line-through; background-color: #FFA0A0 }
</style><table><tbody>
<tr><th>Doc. no.:</th>	<td>N4531</td></tr>
<tr><th>Date:</th>	<td>2015-05-08</td></tr>
<tr><th>Project:</th>	<td>Programming Language C++, Library
Working Group</td></tr>
<tr><th>Revises:</th>	<td>N4316</td></tr>
<tr><th>Reply-to:</th>	<td>Zhihao Yuan &lt;zy at miator dot net&gt;</td></tr>
</tbody></table>
<h1 id="stdrand_replacement_revision_3">std::rand replacement, revision 3</h1>
<div class="maruku_toc"><ul><li><a href="#changes_since_n4316">Changes since N4316</a></li><li><a href="#changes_since_n4217">Changes since N4217</a></li><li><a href="#changes_since_n3796">Changes since N3796</a></li><li><a href="#motivation">Motivation</a></li><li><a href="#design_decisions">Design Decisions</a></li><li><a href="#example">Example</a></li><li><a href="#wording">Wording</a></li><li><a href="#featuretesting_recommendation">Feature-testing recommendation</a></li><li><a href="#sample_implementation">Sample Implementation</a></li><li><a href="#acknowledgments">Acknowledgments</a></li><li><a href="#references">References</a></li></ul></div>
<h2 id="changes_since_n4316">Changes since N4316</h2>

<ul>
<li><code>reseed()</code> (without argument) randomizes the engine.</li>

<li>Uninterested sections removed.</li>

<li>Feature-testing recommendation added.</li>

<li>Wording reworked.</li>
</ul>

<h2 id="changes_since_n4217">Changes since N4217</h2>

<ul>
<li>Rename the seeding utility to <code>reseed</code>, which resets the distributions’ states if needed, based on SG6 comments.</li>

<li>Cleanup the wording with the term “unpredictable state” stolen from Walter’s paper<code>[1]</code>.</li>

<li>Ask the question about exposing the per-thread engine in Future Issues.</li>

<li>Update motivation to reflect the status quo.</li>
</ul>

<h2 id="changes_since_n3796">Changes since N3796</h2>

<ul>
<li>Seeding utility <code>seed_init</code> based on SG6‘s preference.</li>

<li>Variants for <code>std::shuffle</code> and <code>std::experimental::sample</code>.</li>

<li>Naming candidate <code>rand_int</code>.</li>

<li>Some outdated discussions are removed.</li>
</ul>

<h2 id="motivation">Motivation</h2>

<p>The <code>std::rand</code> friends are discouraged in C++14, so we want:</p>

<ol>
<li>
<p>A direct replacement to the <code>std::rand</code> friends. Despite of the security issues, <code>std::rand</code> is considered both handy and useful as a global uniform random number generator.</p>
</li>

<li>
<p>To expose the most widely-used combo in C++11 <code>&lt;random&gt;</code> without pushing the users to learn the whole design. Smoothing the learning curve can usually optimize the acceptance.</p>
</li>
</ol>

<h2 id="design_decisions">Design Decisions</h2>

<p><code>std::rand</code> is a self-contained interface, so its replacement should be independent as well. In addition, I expect the interface to correctly expose the functionalities of <code>&lt;random&gt;</code> and lead to more robust and secure programs. The proposed replacement is</p>

<ul>
<li>
<p>Distribution based. RNG must be used with a distribution; <code>std::rand</code> is a wrong design.</p>
</li>

<li>
<p>Randomly seeded before used. Improper seeding like <code>rand(time(0))</code> may result in vulnerabilities.</p>
</li>

<li>
<p>Per-thread engine. Minimal interface should minimize astonishment, wrt. thread-safety and performance.</p>
</li>

<li>
<p>Manually seedable. User can observe repeatability in a given thread, which is a typical demand for debugging.</p>
</li>

<li>
<p>Type-safe. No integral promotion, no loss of distribution property during down-casting. For a given invocation, the inputs and the result have the same type.</p>
</li>
</ul>

<p>Two variants for the shuffling and sampling algorithms without the explicit <code>URNG</code> parameter are also proposed.</p>

<h2 id="example">Example</h2>

<pre><code>std::randint(0, 6);              // randomly seeded
std::randint(0L, 6L);            // deduced type
std::randint&lt;size_t&gt;(0, 6);      // selected type

std::reseed(0);                  // for debugging purpose
std::shuffle(begin(v), end(v));
std::reseed();                   // back to random</code></pre>

<h2 id="wording">Wording</h2>

<p>Change 26.5.2 [rand.synopsis]:</p>

<pre><code>namespace std {</code></pre>

<blockquote>
<p>…</p>
</blockquote>

<pre><code> // 26.5.7.2, function template generate_canonical
 template&lt;class RealType, size_t bits, class URNG&gt;
   RealType generate_canonical(URNG&amp; g);</code></pre>
<div><ins>
<tt>// 26.5.7.3, function template randint</tt><br />
<tt>template&lt;class IntType&gt;</tt><br />
<tt>&nbsp;&nbsp;IntType randint(IntType a, IntType b);</tt><br />
</ins></div><div><ins>
<tt>void reseed();</tt><br />
<tt>void reseed(default_random_engine::result_type value);</tt><br />
</ins></div>
<pre><code> // 26.5.8.2.1, class template uniform_int_distribution
 template&lt;class IntType = int&gt;
   class uniform_int_distribution;</code></pre>

<blockquote>
<p>…</p>
</blockquote>

<pre><code>} // namespace std</code></pre>

<p>New section 26.5.7.3 [rand.util.randint]:</p>

<blockquote>
<h4 id="26573_function_template_">26.5.7.3 Function template <code>randint</code></h4>
</blockquote>

<blockquote>
<p>A separate <em>per-thread engine</em> of type <code>default_random_engine</code>, initialized to an unpredictable state, shall be maintained for each thread.</p>
</blockquote>

<pre><code>template&lt;class IntType&gt;
  IntType randint(IntType a, IntType b);</code></pre>

<blockquote>
<p><em>Requires:</em> <code>a</code> <em>≤</em> <code>b</code>. If the template argument does not meet the requirements for <code>IntType</code> (26.5.1.1), the program is ill-formed.</p>

<p><em>Returns:</em> A random integer <em>i</em>, <em>a ≤ i ≤ b</em>, produced from a thread-local instance of <code>uniform_int_distribution&lt;IntType&gt;</code> (26.5.8.2.1) invoked with the per-thread engine.</p>
</blockquote>

<pre><code>void reseed();
void reseed(default_random_engine::result_type value);</code></pre>

<blockquote>
<p><em>Effects:</em> Let <code>g</code> be the per-thread engine (26.5.7.3). The first form sets <code>g</code> to an unpredictable state. The second form invokes <code>g.seed(value)</code>.</p>

<p><em>Postcondition:</em> Subsequent calls to <code>randint</code> (26.5.7.3) do not depend on values produced by <code>g</code> before calling <code>reseed</code>. <em>[Note:</em> <code>reseed</code> also resets any instances of <code>uniform_int_distribution</code> used by <code>randint</code>. <em>–end note]</em></p>
</blockquote>

<p>Change 25.1 [algorithms.general]:</p>

<blockquote>
<h3 id="header__synopsis">Header <code>&lt;algorithm&gt;</code> synopsis</h3>

<p>…</p>
</blockquote>

<pre><code> // 25.3.12, shuffle:</code></pre>
<div><ins>
<tt>template&lt;class RandomAccessIterator&gt;</tt><br />
<tt>&nbsp;&nbsp;void shuffle(RandomAccessIterator first,
RandomAccessIterator last);</tt>
</ins></div>
<pre><code> template&lt;class RandomAccessIterator, class UniformRandomNumberGenerator&gt;
   void shuffle(RandomAccessIterator first,
                RandomAccessIterator last,
                UniformRandomNumberGenerator&amp;&amp; g);</code></pre>

<p>Change 25.3.12 [alg.random.shuffle]:</p>
<div><ins>
<tt>template&lt;class RandomAccessIterator&gt;</tt><br />
<tt>&nbsp;&nbsp;void shuffle(RandomAccessIterator first,
RandomAccessIterator last);</tt>
</ins></div>
<pre><code> template&lt;class RandomAccessIterator, class UniformRandomNumberGenerator&gt;
   void shuffle(RandomAccessIterator first,
                RandomAccessIterator last,
                UniformRandomNumberGenerator&amp;&amp; g);</code></pre>

<blockquote>
<p>…</p>

<p><em>Remarks:</em> <ins>If <code>g</code> is not given in the argument list, it denotes the per-thread engine (26.5.7.3).</ins> To the extent that the implementation of this function makes use of random numbers, the object <code>g</code> shall serve as the implementation’s source of randomness.</p>
</blockquote>

<p>The following wording is relative to N4529 <strong>[fund.ts2]</strong>.</p>

<blockquote>
<p><em>[Editorial note:</em> Please consider referring the C++17 working paper. <em>–end note]</em></p>
</blockquote>

<p>Change 12.3 [alg.random.sample]:</p>
<div><ins>
<tt>template&lt;class PopulationIterator, class SampleIterator,
class Distance&gt;</tt><br />
<tt>SampleIterator sample(PopulationIterator first, PopulationIterator
last,</tt><br />
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SampleIterator
out, Distance n);</tt>
</ins></div>
<pre><code> template&lt;class PopulationIterator, class SampleIterator,
          class Distance, class UniformRandomNumberGenerator&gt;
 SampleIterator sample(PopulationIterator first, PopulationIterator last,
                       SampleIterator out, Distance n,
                       UniformRandomNumberGenerator&amp;&amp; g);</code></pre>

<blockquote>
<p>…</p>

<p><em>Remarks:</em></p>

<ul>
<li>Stable if and only if <code>PopulationIterator</code> meets the requirements of a <code>ForwardIterator</code> type.</li>

<li><ins>If <code>g</code> is not given in the argument list, it denotes the per-thread engine (26.5.7.3).</ins> To the extent that the implementation of this function makes use of random numbers, the object <code>g</code> shall serve as the implementation’s source of randomness.</li>
</ul>
</blockquote>

<h2 id="featuretesting_recommendation">Feature-testing recommendation</h2>

<p>Please use <code>randint</code> as the macro name suffix in the library category.</p>

<h2 id="sample_implementation">Sample Implementation</h2>

<p>A sample implementation is available at <a href="https://github.com/lichray/randint">https://github.com/lichray/randint</a>.</p>

<h2 id="acknowledgments">Acknowledgments</h2>

<p>Hans Boehm, who emphasized the importance of enforcing the per-thread random engine more than once.</p>

<p>Stephan T. Lavavej, who carefully reviewed this paper and provided many corrections.</p>

<p>Walter E. Brown, who drafted the paper<code>[1]</code> which contains basically the same thought.</p>

<p>And many others who joined the <code>std::rand</code> related discussions on <em>c++std-lib</em> and <em>c++std-lib-ext</em> mailing lists.</p>

<h2 id="references">References</h2>

<p><code>[1]</code> Brown, Walter E. N3742 <em>Three <code>&lt;random&gt;</code>-related Proposals, v2</em>. <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3742.pdf">http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3742.pdf</a></p>

<p><code>[2]</code> <em><code>random</code> – Generate pseudo-random numbers</em>. “The Python Standard Library”. <a href="http://docs.python.org/2/library/random.html">http://docs.python.org/2/library/random.html</a></p>
</body></html>
