feat(std/random): add Random, a seedable and splittable SplitMix64 generator #159

Merged
argus merged 2 commits from loop/3-std-random into main 2026-10-07 18:25:24 +00:00
Collaborator

Closes #3

What

std/random with Random: a generator that is a value.

  • Random.seeded(seed), uint64(), float() (53 bits, in [0, 1)), int(range) (uniform by rejection, so no modulo bias; the full Int range works), split(), shuffled/shuffle (Fisher-Yates), choice, sample.
  • SplitMix64, declared stable (owner decision recorded in #3 and docs/design/RANDOM.md section 2). Normal and other continuous distributions wait for std/statistics.
  • Seeds for unpredictable use come from Entropy of std/os; the module comment says plainly that this is not a cryptographic generator.
  • docs/standard-library/random.md is new; RANDOM.md section 2 now freezes the mappings; the roadmap and URI.md are updated; the standard-library index and skills/ are regenerated.

Tests

24 tests in std/random/tests/random.test.trb. The known-answer tests for seeds 0 and 1234567 use the published SplitMix64 vectors. The mappings (integers, floats, shuffle, choice, sample, split) are pinned with values computed by an independent Python model of the spec; the split values pin the construction (Java SplittableRandom style) and do not prove statistical independence on their own.

Verification, honestly

The machine this was built on has no C compiler, so only the VM toolchain was available. Run locally in the VM: torb check . (537637 of 537637 expressions typed, 0 deferred), torb format --check . (0 of 1108 files would change), torb lint std/random (no findings), torb test std/random (24 passed), torb docs index/skill/site --check (up to date, no broken link), tools/check-commits.sh main (ok). torb docs check docs reports 38 problems on main and still 38 with this change (none in the new files; they are the missing C compiler and translation keys of the VM toolchain).

Not run locally: tools/gates.sh a (needs the native bootstrap) and tier B. Forge CI has to cover those.

Closes #3 ## What `std/random` with `Random`: a generator that is a value. - `Random.seeded(seed)`, `uint64()`, `float()` (53 bits, in `[0, 1)`), `int(range)` (uniform by rejection, so no modulo bias; the full `Int` range works), `split()`, `shuffled`/`shuffle` (Fisher-Yates), `choice`, `sample`. - SplitMix64, declared stable (owner decision recorded in #3 and `docs/design/RANDOM.md` section 2). Normal and other continuous distributions wait for `std/statistics`. - Seeds for unpredictable use come from `Entropy` of `std/os`; the module comment says plainly that this is not a cryptographic generator. - `docs/standard-library/random.md` is new; `RANDOM.md` section 2 now freezes the mappings; the roadmap and `URI.md` are updated; the standard-library index and `skills/` are regenerated. ## Tests 24 tests in `std/random/tests/random.test.trb`. The known-answer tests for seeds 0 and 1234567 use the published SplitMix64 vectors. The mappings (integers, floats, shuffle, choice, sample, split) are pinned with values computed by an independent Python model of the spec; the split values pin the construction (Java `SplittableRandom` style) and do not prove statistical independence on their own. ## Verification, honestly The machine this was built on has no C compiler, so only the VM toolchain was available. Run locally in the VM: `torb check .` (537637 of 537637 expressions typed, 0 deferred), `torb format --check .` (0 of 1108 files would change), `torb lint std/random` (no findings), `torb test std/random` (24 passed), `torb docs index/skill/site --check` (up to date, no broken link), `tools/check-commits.sh main` (ok). `torb docs check docs` reports 38 problems on `main` and still 38 with this change (none in the new files; they are the missing C compiler and translation keys of the VM toolchain). Not run locally: `tools/gates.sh a` (needs the native bootstrap) and tier B. Forge CI has to cover those.
Refs #3. Seeding, 64-bit and float draws, uniform integers of a range by rejection, shuffling, choice, sampling and splitting, with the published SplitMix64 vectors as known-answer tests.
docs(random): document std/random and mark RANDOM.md slice 1 built
Some checks failed
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 3m9s
ci / every host emits the same C (pull_request) Successful in 13m6s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 9m16s
ci / pack the seed (pull_request) Successful in 26s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
images / cr.torb.dev/torbscript/registry (push) Has been skipped
images / cr.torb.dev/torbscript/release-sync (push) Has been skipped
images / cr.torb.dev/torbscript/site (push) Has been skipped
ci / commit messages (push) Successful in 13s
ci / what the change touches (push) Successful in 12s
images / cr.torb.dev/torbscript/site:edge (main) (push) Successful in 19m5s
pdisc / pdisc (push) Failing after 2m33s
ci / which runners exist (push) Successful in 5s
ci / bootstrap and conformance (windows-x64) (push) Has been skipped
ci / bootstrap and conformance (linux-arm64) (push) Has been skipped
ci / bootstrap and conformance (macos-arm64) (push) Has been skipped
ci / bootstrap (linux-x64) (push) Successful in 5m2s
ci / cross-compiled on linux-x64 (windows-x64) (push) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (push) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (push) Has been skipped
ci / the VS Code extension (editors/vscode) (push) Successful in 44s
ci / tier A (linux-x64) (push) Successful in 24m53s
ci / tier B (linux-x64) (push) Successful in 31m58s
ci / pack the seed (push) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (push) Successful in 3m54s
ci / every host emits the same C (push) Successful in 7m26s
ci / archives (push) Has been skipped
ci / the playground (torb as WebAssembly) (push) Successful in 4m40s
ci / gates (push) Successful in 0s
9e2ab91dc0
Closes #3. Adds the std/random page, freezes the mappings in RANDOM.md section 2, updates the roadmap and URI.md, and regenerates the indexes and skills.
argus approved these changes 2026-10-07 18:25:21 +00:00
argus left a comment

Checklist for 9e2ab91 (CI combined status: success; gates, tier A, bootstrap linux-x64, pdisc, commit messages green).

  • Tests: ok. 24 tests; known-answer vectors for seeds 0 and 1234567 match the published SplitMix64 outputs (seed 0 starts 0xe220a8397b1dcdaf), plus pinned mappings for int (incl. negative bounds, one-number range, full Int range), float, shuffle, choice, sample and split.
  • Correctness: ok. Mixing constants, state advance before mix, rejection limit (2^64 - count) % count, the count == 0 case for the full range, bitsOf/numberOf two's-complement round trip, Fisher-Yates bounds and split (state = next output, gamma = mixGamma of the following state) all match the reference and Java's SplittableRandom, and agree with the frozen text in RANDOM.md section 2.
  • Scope = task: ok. Implements #3 as decided by the owner in the issue (SplitMix64 declared stable; ints, floats, shuffle, sample/choice, split; no statistics distributions). No compiler, runtime or seed change.
  • Security/secrets: ok. Pure UInt64 code, no capability, no dependency; the not-for-cryptography warning is in the module and type docs.
  • Data: ok (new package, nothing stored).
  • Docs: ok. New docs/standard-library/random.md, RANDOM.md section 2, ROADMAP, URI.md, indexes and generated skill copies updated; pdisc green.
  • Architecture/placement: ok. New std/random package follows the existing std/* layout.

Non-blocking:

  1. The # Panics cases (empty range in int, bad count in sample) have no test; add one if the test runner can assert a panic.
  2. bitsOf/numberOf/gammaOf/bitCount are private free functions; #146 may want them as methods later.
Checklist for 9e2ab91 (CI combined status: success; gates, tier A, bootstrap linux-x64, pdisc, commit messages green). - Tests: ok. 24 tests; known-answer vectors for seeds 0 and 1234567 match the published SplitMix64 outputs (seed 0 starts 0xe220a8397b1dcdaf), plus pinned mappings for int (incl. negative bounds, one-number range, full `Int` range), float, shuffle, choice, sample and split. - Correctness: ok. Mixing constants, state advance before mix, rejection limit `(2^64 - count) % count`, the `count == 0` case for the full range, `bitsOf`/`numberOf` two's-complement round trip, Fisher-Yates bounds and `split` (state = next output, gamma = `mixGamma` of the following state) all match the reference and Java's `SplittableRandom`, and agree with the frozen text in RANDOM.md section 2. - Scope = task: ok. Implements #3 as decided by the owner in the issue (SplitMix64 declared stable; ints, floats, shuffle, sample/choice, split; no statistics distributions). No compiler, runtime or seed change. - Security/secrets: ok. Pure `UInt64` code, no capability, no dependency; the not-for-cryptography warning is in the module and type docs. - Data: ok (new package, nothing stored). - Docs: ok. New `docs/standard-library/random.md`, RANDOM.md section 2, ROADMAP, URI.md, indexes and generated skill copies updated; pdisc green. - Architecture/placement: ok. New `std/random` package follows the existing `std/*` layout. Non-blocking: 1. The `# Panics` cases (empty range in `int`, bad `count` in `sample`) have no test; add one if the test runner can assert a panic. 2. `bitsOf`/`numberOf`/`gammaOf`/`bitCount` are private free functions; #146 may want them as methods later.
argus merged commit 9e2ab91dc0 into main 2026-10-07 18:25:24 +00:00
argus deleted branch loop/3-std-random 2026-10-07 18:25:25 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!159
No description provided.