Rakugrid
The behavioural grid of the Raku language — every recorded test, on every engine on record.
Roast asks whether an implementation is Raku. Rakugrid asks whether it survives real programs: small constructs (atoms) and their combinations (molecules), each crossed against a ladder of awkward values, each cell recording what every engine on record actually printed. The suite is its own dataset — this site is that dataset, browsable.
The whole suite, one pixel per test
Every test in the suite, grouped by family — a gap separates atoms. Hover names the atom; click opens it. The colored streaks are divergence clusters: one root cause is usually one streak.
operators112,415 tests · 147 atoms
methods29,142 tests · 103 atoms
regexes11,776 tests · 92 atoms
signatures13,923 tests · 15 atoms
syntax434 tests · 13 atoms
spelling952 tests · 119 atoms
laws3,051 tests · 33 atoms
types44 tests · 8 atoms
molecules204 tests · 3 atoms
regression260 tests · 260 atoms
numeric4 tests · 1 atom
unicode3 tests · 1 atom
io2 tests · 1 atom
hangs1 tests · 1 atom
How to read a cell
A test is one record in a .grid file: the code, the asserted behaviour, and one oracle line per engine that ever ran it — newest observation last:
- id 0005
from ladder:mixed×mixed
cell 0 | NaN
code (0) cmp (NaN)
is Order::Less
type Order
oracle rakudo-2026.07 → Order::Less
oracle rakupp-v3.14.0-77-gf431f48-dirty → Order::LessThe colors compare each record’s newest rakupp observation with the reference: agree and differs mean what they say; crash means the engine went down rather than answering; ruled means the divergence was adjudicated by hand; no data means one side was never recorded. An observation is a snapshot, not a verdict on today’s binary: a differing cell says the engines disagreed when that cell was last probed, and the drawer names the exact build that said it. The rakupp snapshots accumulate on purpose — a sweep re-probes only what changed, so an untouched cell keeps the build that last ran it instead of costing a fresh run of the whole grid.
The oracle is not the arbiter
Where the engines disagree, Rakudo’s answer is the default, not the law. A divergence must either be fixed or receive a signed verdict naming which behaviour is right and why — otherwise the build fails. Sometimes the verdict goes against the reference:
(1).asinh
| reference | 0.8813735870195429e0 |
| rakupp | 0.881373587019543e0 |
| ruling | impl-bug asinh(1) = ln(1+sqrt 2); the correctly-rounded double is 0.881373587019543, and the reference is one ULP below it |
All 3,489 signed rulings are on the rulings page; the 367 recorded crash observations have their own.
The sweep, over time
Each point is one measured run of the whole suite against a rakupp build. The failing count only means something while the suite holds still, so its line breaks wherever the suite grew.
The newest point predates the suite's growth: that sweep ran 41,412 of the 42,402 tests the suite held then, and the suite holds 172,211 today — a full-grid sweep has not been recorded since. Only these charts wait for one: the colors above come from the observations each record already carries, so they cover the whole grid.
the measured points
| date | ran | failed | note |
|---|---|---|---|
| 2026-08-16 | 24,144 | 9,518 | baseline: the sweep starts here |
| 2026-08-16 | 24,144 | 6,874 | batch 1+2: `$!` from a returned Failure; take/emit; Cool numerics; .raku itemisation |
| 2026-08-16 | 24,144 | 6,195 | batch 3: strict numification, Any.join/Mu.bless/Cool.chrs |
| 2026-08-16 | 24,144 | 5,490 | batch 4: argument shapes (uniprop, same-*, join, roots, unpolar) |
| 2026-08-16 | 24,144 | 5,166 | batch 5: chomp needle, Any.Capture, roots(1), Code.Str |
| 2026-08-16 | 24,144 | 5,011 | batch 6: min/max ties, NaN ordering, Cool.Failure — 3 Roast regressions, fixed in 7 |
| 2026-08-16 | 24,144 | 4,930 | batch 7: scalar-numeric strictness + the batch-6 repairs |
| 2026-08-17 | 41,412 | 10,153 | SUITE GREW to 42,402 records (operator inventory matrix): not comparable to the rows above |
| 2026-08-17 | 41,412 | 9,015 | operator spellings: !== is negated ==, plus the unicode equality and negated-set forms |
| 2026-08-17 | 41,412 | 8,469 | empty Set/Bag/Mix .raku is the sub form; ~< and ~> are no-such-operator, not NYI |
| 2026-08-17 | 41,412 | 8,078 | ≼/≽ removed-in-6.d diagnostic; bitwise ops reject a non-finite operand |
| 2026-08-17 | 41,412 | 7,950 | exact numification of Hash/type-object operands; `.` as infix is X::Obsolete |
| 2026-08-17 | 41,412 | 7,842 | Any.nl-out (documented); the rest of the "internals" cluster triaged against the docs |
| 2026-08-17 | 41,412 | 7,842 | constants immutable + ++/-- honour readonly — grid flat, Roast 600 (misc.t 11→15, advent2009-day09 full) |
Run it yourself
The suite is engine-neutral and lives at github.com/ash/rakugrid. The harness runs unchanged under any implementation:
raku bin/rakugrid fire --engine=/path/to/rakupp # run everything, emit TAP
raku bin/rakugrid matrix operators/infix-cmp # one atom as a matrix
raku bin/rakugrid isolate 'grid:operators/infix-cmp#0005' # one test, standalone
raku bin/rakugrid check # the build rule: no unsigned divergencesEvery test on this site has a “run in the playground” button — the code runs in your browser on the same engine that powers the playground.