module rand
module lib/rand.mu
import "rand"
rand provides a small pseudo-random number generator.
This is a Lehmer generator over the Mersenne prime 2^61-1: deterministic, reproducible from a given seed, and adequate for shuffling a deck or picking a colour. It is NOT suitable for anything where predicting the next value matters -- keys, tokens, nonces -- because the whole sequence follows from any one value.
The seed is taken from the clock on first use. Call seed() to make a run reproducible.
Imports
Functions
below#
below returns a pseudo-random integer in [0, bound).
Source lib/rand.mu:65
fn below(bound) {
if !typing.is_int(bound) {
return error("rand.below expects integer bound, got " + type(bound))
}
if bound <= 0 {
return error("rand.below expects a positive bound, got " + str(bound))
}
return int() % bound
}between#
between returns a pseudo-random integer in [low, high], both inclusive.
Source lib/rand.mu:76
fn between(low, high) {
if !typing.is_int(low) {
return error("rand.between expects integer low, got " + type(low))
}
if !typing.is_int(high) {
return error("rand.between expects integer high, got " + type(high))
}
if low > high {
return error("rand.between expects low <= high, got " + str(low) + " > " + str(high))
}
return low + below(high - low + 1)
}choice#
choice returns a pseudo-random element of a non-empty list.
Source lib/rand.mu:90
fn choice(items) {
if !typing.is_list(items) {
return error("rand.choice expects list items, got " + type(items))
}
if len(items) == 0 {
return error("rand.choice expects a non-empty list")
}
return items[below(len(items))]
}int#
int returns the next pseudo-random non-negative integer.
Source lib/rand.mu:55
fn int() {
_ensure_seeded()
_state = (_state * _MULTIPLIER) % _MODULUS
if _state < 0 {
_state = -_state
}
return _state
}seed#
seed fixes the generator's starting point, making a run reproducible. Any integer will do; 0 is replaced with 1, since 0 is this generator's one fixed point and would make every subsequent value 1.
Source lib/rand.mu:23
fn seed(value) {
if !typing.is_int(value) {
return error("rand.seed expects integer value, got " + type(value))
}
_state = value % _MODULUS
if _state < 0 {
_state = -_state
}
if _state == 0 {
_state = 1
}
return nil
}shuffle#
shuffle returns a new list holding the same elements in pseudo-random order, leaving the input untouched. Fisher-Yates, so every ordering is equally likely as far as the generator is.
Source lib/rand.mu:103
fn shuffle(items) {
if !typing.is_list(items) {
return error("rand.shuffle expects list items, got " + type(items))
}
out := []
i := 0
while i < len(items) {
out = append(out, items[i])
i = i + 1
}
i = len(out) - 1
while i > 0 {
j := below(i + 1)
swap := out[i]
out[i] = out[j]
out[j] = swap
i = i - 1
}
return out
}Internal helpers
Underscore-prefixed names are implementation detail. They are listed so the module's source reads without surprises, not as API — they may change at any time.
| _MODULUS | — |
| _MULTIPLIER | — |
| _ensure_seeded() | _ensure_seeded seeds from the clock the first time a value is asked for. |
| _state | — |