Module rand
Non-cryptographic pseudo-random numbers — seedable, reproducible, fast
(plans/STD_API_AUDIT.md §7 P0 item 7). CLEARLY SEPARATE from
std/crypto/random, which is the OS entropy source: use THAT for keys,
tokens and anything an adversary must not predict; use THIS for
simulations, property tests, shuffles and games, where reproducibility
from a seed is the point.
The generator is PCG-XSH-RR 64/32 (O'Neill, pcg-random.org) — 64-bit state, 32-bit output, period 2^64 per stream.
{ Rng, rand_range } :: import "std/rand";
rng := Rng.new(u64(42));
d6 := rng.range(i64(1) .. i64(7)); // uniform in [1, 7), reproducible
d20 := rand_range(i64(1) .. i64(21)); // the process-global generator
Stability
Stable. The sequence a given seed produces is part of the contract — a
test that pins Rng.new(42)'s first draws must keep passing, so the
algorithm and its constants will not change under a patch release.
Types
Seedable PCG32 generator state.
Fields
| Name | Type | Description |
|---|---|---|
_st | _RngState |
impl(Rng, ...)
with_stream : (Rng) fn(seed : u64, stream : u64) -> RngA generator on an explicit stream: distinct stream values give
statistically independent sequences for the same seed (the PCG
initseq parameter).
Parameters
| Name | Type | Notes |
|---|---|---|
seed | u64 | |
stream | u64 |
Returns: Rng
new : (Rng) fn(seed : u64) -> RngA generator on the default stream, seeded with seed. The same seed
always produces the same sequence.
Parameters
| Name | Type | Notes |
|---|---|---|
seed | u64 |
Returns: Rng
from_entropy : (Rng) fn() -> RngA generator seeded from OS entropy — unpredictable, and therefore NOT
reproducible. Use new(seed) when a test needs to replay a sequence.
Falls back to a fixed seed only if the platform entropy source fails,
which on every supported target means the process is already doomed.
Returns: Rng
next_u32 : (Rng) fn(self : Rng) -> u32next_u64 : (Rng) fn(self : Rng) -> u64next_f64 : (Rng) fn(self : Rng) -> f64A uniform float in [0, 1) (53 bits of precision — an exact division
by 2^53, not a hand-typed epsilon literal, which parsed LOW).
Parameters
| Name | Type | Notes |
|---|---|---|
self | Rng |
Returns: f64
next_bool : (Rng) fn(self : Rng) -> boolA fair coin. Reads the TOP bit, which is the best-mixed one in a PCG
output word — x % 2 on the low bit is a classic weak-bit mistake.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Rng |
Returns: bool
next_below : (Rng) fn(self : Rng, bound : u64) -> u64A uniform value below bound, rejection-sampled. Panics for
bound == 0.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Rng | |
bound | u64 |
Returns: u64
range : (Rng) fn(self : Rng, r : Range(i64)) -> i64A uniform integer in the half-open range r — write it with ..:
rng.range(i64(1) .. i64(7)) for a d6. Panics if the range is empty
(r.end <= r.start), like Rust's gen_range — an empty range has no
value to return.
The range is a Range(i64) rather than two i64 parameters so the
half-open bound is visible AT THE CALL SITE: range(1, 7) reads as
either [1, 7) or [1, 7] and the caller has to remember which.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Rng | |
r | Range(i64) |
Returns: i64
range_inclusive : (Rng) fn(self : Rng, r : RangeInclusive(i64)) -> i64A uniform integer in the INCLUSIVE range r — rng.range_inclusive(i64(1) ..= i64(6)).
Panics if the range is empty (r.end < r.start).
A separate method rather than an overload of range: Yo has no
function overloading (plans/reference/FUNCTION_OVERLOADING_POLICY.md),
and the alternative — one range over a SampleRange-style trait —
would put a trait on the public surface to save one word at the call
site.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Rng | |
r | RangeInclusive(i64) |
Returns: i64
shuffle : (Rng) fn(generic(T) self : Rng, xs : ArrayList(T)) -> unitFunctions
32 uniformly random bits from the process-global generator.
Returns: u32
64 uniformly random bits from the process-global generator.
Returns: u64
A uniform float in [0, 1) from the process-global generator.
Returns: f64
A fair coin from the process-global generator.
Returns: bool
A uniform value below bound from the process-global generator,
rejection-sampled. Panics for bound == 0.
Parameters
| Name | Type | Notes |
|---|---|---|
bound | u64 |
Returns: u64
A uniform integer in the half-open range r, from the process-global
generator — rand_range(i64(1) .. i64(7)). Panics on an empty range.
Parameters
| Name | Type | Notes |
|---|---|---|
r | Range(i64) |
Returns: i64
A uniform integer in the INCLUSIVE range r, from the process-global
generator — rand_range_inclusive(i64(1) ..= i64(6)). Panics on an empty
range.
Parameters
| Name | Type | Notes |
|---|---|---|
r | RangeInclusive(i64) |
Returns: i64