Module std::rand
Randomness as an effect: code draws random numbers only through a Random capability, and
fault points only through Draw, so its caller decides where the answers come from. The root
supplies no Random: OsRandom draws the operating system's entropy through the root's
Sys, std::sim::SimRandom is a seeded generator, and Calm answers every Draw the
common way.
Source: std/rand.weir; committed interface: std/rand.iface. Index
- effect
Random: A stream of random numbers;OsRandomdraws them from the OS,std::sim::SimRandomdeterministically from a seed. - handler
OsRandom: The operating system's entropy asRandom, for unpredictable numbers (a hash seed, a token, retry jitter). - effect
Draw: A draw whose answer the caller decides, of the shapes a simulation spends its randomness on: which ofnthings happens next, how long something takes, whether a rare thing (a fault) happens, and how much ofna short count moves.std::sim::Sampledanswers from a seeded generator,std::sim::Searchedmakes each draw aweir explorechoice point and bounds the faults a path takes, andCalmanswers the common case, as a production run does. - handler
Calm: Every draw its common answer: the first ofn, no delay, no fault, the least part. Install it (with Calm { … }) to run production code that has fault points.
effect Random
pub effect Random {
fn next() -> Int;
}
A stream of random numbers; OsRandom draws them from the OS, std::sim::SimRandom
deterministically from a seed.
op next
fn next() -> Int;
Control kind tail: the clause's result is the op's, and the performer goes on, never aborted or suspended.
The next number of the sequence, at least 0.
handler OsRandom
pub handler OsRandom(mut buf: [u8; 256], mut left: usize) for Random with Sys
The operating system's entropy as Random, for unpredictable numbers (a hash seed, a token,
retry jitter).
Install it over the root's Sys as with OsRandom([0u8; 256], 0) { … }: each next() is
eight bytes the device drew, the top bit cleared, so it is at least 0. It draws 256 bytes at a
time, one system call per 32 numbers; left counts the bytes of buf not yet handed out,
taken from its end, so install it empty (0); any left above 256 refills as 0 does.
Natively the bytes are getrandom(2)'s, and under weir run the host's; under
WEIR_DEVICE=sim, weir explore, weir test and the playground they are the simulated
device's fixed stream, so a run is reproducible there and nowhere else.
Handles Random, with clauses:
effect Draw
pub effect Draw {
fn pick(n: Int) -> Int;
fn delay(max: Int) -> Int;
fn fault(p: Int) -> Bool;
fn part(n: Int) -> Int;
}
A draw whose answer the caller decides, of the shapes a simulation spends its randomness on:
which of n things happens next, how long something takes, whether a rare thing (a fault)
happens, and how much of n a short count moves. std::sim::Sampled answers from a seeded
generator, std::sim::Searched makes each draw a weir explore choice point and bounds the
faults a path takes, and Calm answers the common case, as a production run does.
op pick
fn pick(n: Int) -> Int;
Control kind tail: the clause's result is the op's, and the performer goes on, never aborted or suspended.
One of 0..n; 0 when n is 1 or less.
op delay
fn delay(max: Int) -> Int;
Control kind tail: the clause's result is the op's, and the performer goes on, never aborted or suspended.
A delay in 0..=max; 0 when max is 0 or less.
op fault
fn fault(p: Int) -> Bool;
Control kind tail: the clause's result is the op's, and the performer goes on, never aborted or suspended.
Whether the rare thing happens: sampled, p times in a hundred; never when p is 0 or less.
op part
fn part(n: Int) -> Int;
Control kind tail: the clause's result is the op's, and the performer goes on, never aborted or suspended.
A strictly short part of n > 1 things, in 1..n; 1 when n is 2 or less.
handler Calm
pub handler Calm: shared for Draw
Every draw its common answer: the first of n, no delay, no fault, the least part. Install it
(with Calm { … }) to run production code that has fault points.
Handles Draw, with clauses: