User Guide¶
Mutable Generators¶
Mutable generators extend Kotlin's Random:
import one.wabbit.random.L64X128Random
val rng = L64X128Random(seed = 7L)
val value = rng.nextInt(10)
check(value in 0 until 10)
Use them when existing APIs expect kotlin.random.Random or when mutable state is simpler than
passing explicit continuation values.
Immutable Generators¶
Immutable generators return RandomResult:
import one.wabbit.random.ThreefryRandom
val start = ThreefryRandom.Immutable(seed = 99L)
val first = start.next32()
val second = first.generator.next32()
check(first.generator != start)
check(first.value != second.value)
Store RandomResult.generator and use it for the next sample.
Forking and Splitting¶
L64X128Random supports forking:
val parent = L64X128Random(seed = 1L)
val child = parent.fork()
check(child.nextLong() != parent.nextLong())
ThreefryRandom supports JAX-style key derivation:
val key = ThreefryRandom(seed = 1L)
val (left, right) = key.split2()
val folded = key.foldIn(123)
check(left != right)
check(folded != key)
Counter-Based Blocks¶
PhiloxRandom.nextBlock() returns the next 4x64 block and advances the exact counter:
import one.wabbit.random.PhiloxRandom
val philox = PhiloxRandom(key0 = 1L, key1 = 2L)
val block = philox.nextBlock()
check(block.size == 4)
Use advance or jumped to move through the counter space without sampling intermediate blocks.
Serializable Checkpoints¶
Immutable classes are serializable with kotlinx.serialization:
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import one.wabbit.random.Xoshiro256StarStarRandom
val snapshot = Xoshiro256StarStarRandom(seed = 42L).asImmutable()
val encoded = Json.encodeToString(snapshot)
val decoded = Json.decodeFromString<Xoshiro256StarStarRandom.Immutable>(encoded)
check(decoded == snapshot)
Reproducibility¶
For exact reproducibility, keep the same generator type, seed/state, version, and consumption
pattern. Mixing next32, next64, nextBytes, and block APIs may intentionally change alignment.