How do I generate random numbers, and make them reproducible, in EK9?
← Advanced Type System · Ref: Q1368
Randomness in EK9 is behind the Random trait, with two implementations - following the same injectable pattern as Clock / SystemClock.
THE RANDOM TRAIT
next() full-range Integer next(lower, upper) Integer in the inclusive range [lower, upper] nextFloat() Float in [0.0, 1.0) nextBoolean() Boolean
TWO IMPLEMENTATIONS
SystemRandom() production - non-deterministic (a different sequence each run) SeededRandom(seed) reproducible - a given seed yields a PINNED sequence, the same across runs and JVMs
WHY IT MATTERS
Because behaviour is behind a trait, code depends on Random and you inject the implementation. In production inject SystemRandom; in tests inject SeededRandom (or a mock) so anything using randomness becomes deterministic and its output can be asserted. Using SystemRandom in a test gives flaky, unrepeatable results - reach for SeededRandom there instead.
EXAMPLE (REPRODUCIBLE DICE)
rnd <- SeededRandom(42) d1 <- rnd.next(1, 6) // inclusive 1..6 d2 <- rnd.next(1, 6)
The (lower, upper) bounds are inclusive and match OS().random(lower, upper).
Note there is no shuffle/choice primitive - write a small helper over next(l, u) if you need to reorder or pick from a List.
Clock / SystemClock is the sibling injectable pair. Use 'ek9 -h SeededRandom' for the full API.
Example
defines module qa.random.usage defines program RandomUsage() stdout <- Stdout() //Reproducible: the same seed yields the same sequence every run. rnd <- SeededRandom(42) d1 <- rnd.next(1, 6) d2 <- rnd.next(1, 6) stdout.println(`dice: ${d1} ${d2}`) f <- rnd.nextFloat() stdout.println(`float in [0,1): ${f}`)
Other ways to ask this
- How do I seed a random number generator in EK9?
- How do I make randomness deterministic in tests?
- What is the difference between SystemRandom and SeededRandom?
- How do I roll a dice or pick a random value?
Coming from another language?
Java: java.util.Random(seed) / ThreadLocalRandom. Python: random.seed / random.Random(seed). Go: math/rand with a seeded Source. Rust: rand crate with StdRng::seed_from_u64. EK9: a Random trait with SystemRandom (non-deterministic) and SeededRandom(seed) (reproducible), modelled on the injectable Clock/SystemClock pair; next()/next(l,u inclusive)/nextFloat/nextBoolean.
Keywords: trait, test, random, seed, seeded, seededrandom, reproducible, shuffle, inject, systemrandom, deterministic, dice, next