RCE language specification, draft 0.5
RCE language specification
Abstract. RCE is a small programming language whose programs mean one thing everywhere. A program is turned into a Form: a state machine given by its states, its events, a step function that maps a state and an event to a new state and an outcome, and the log of events. Every runtime that runs the Form must produce the same results bit for bit, and the rules that make this so are checked by machine.
Figure (informative). The pipeline from source to Form, log, emit targets and host. Source: docs/figures.
Three plain points:
- Same answer on every target. Arithmetic, text, floats and concurrency have one defined meaning; there is no undefined behaviour.
- Every program ends. Loops, recursion and iterators are bounded, so the step function always returns.
- Memory is safe by construction. Ownership, second-class borrows, regions and linear handles rule out use-after-free and data races.
Tiny example (a counter that refuses to go negative):
Reading map. Files are in spec/book/ and are meant to be read in order:
| File | What it covers |
|---|---|
00-overview.md | this abstract, status and how the spec is checked |
01-notation.md | how grammar and typing rules are written; what conformance means |
02-lexical.md | characters, comments, tokens, keywords, literals, indentation |
03-syntax.md | the full grammar of declarations, types, statements, expressions |
04-programs.md | modules, the program's Form, scope |
05-types-ownership.md | types, contexts, typing rules, ownership, borrowing |
06-regions-effects-extensions.md | arenas, concurrency, traits, comptime, foreign functions, linear types, device regions, iterators |
07-form-evaluation.md | the Form of a program, evaluation, exact edge cases of every primitive |
08-steps-loops-concurrency.md | the step function, errors, hashing, loops, tasks, examples |
09-wellformedness.md | the list of rules a program must pass to be accepted |
10-theorems.md | the theorems and what is proved in Lean |
11-decisions.md | design decisions and the changes per draft |
12-tooling.md | the rce command line and language server |
13-references.md | sources |
14-draft06-concurrency.md | Appendix C: the version 0.6 concurrency extensions and version 0.7 (only for modules declaring # rce-version: 0.6 or 0.7, 2.7; C.15) |
15-handler-spec-profile.md | Appendix D: the engine profile, handler specs and fits, including reads, joins and scans |
INDEX.md lists every file with its hash; READ-PROTOCOL.md says how an
agent proves it read the spec. RCE-SPEC.md is all of these files joined
into one, generated by rce-book build.
Status. Draft 0.7, 2026-10-13. Status: for review. Version 0.7
(C.15) is version 0.6 with size-scaled standard library method costs
(C.6.4); it is the only semantic difference between them, and every
other change since draft 0.6 is an erratum that applies to every version
(C.15). Versions 0.5 and 0.6 are still accepted with their meaning
unchanged. Version 0.5
(sections 2 to 10) is unchanged from draft 0.5 except for the version
declaration of 2.7 and rules W-VER-1, W-MOD-3 and W-TRAIT-3 now listed in
section 7. Version 0.6 (Appendix C) is new in this draft: it is what the
reference checker and the Lean files enforce and prove, and it applies
only to modules that declare it, so every valid 0.5 program is still
accepted. The core is mechanized in Lean 4
(spec/lean/, section 8), a reference type and well-formedness checker
(spec/checker/, rce-check) implements sections 4, 5 and 7 including the
admission gate of 6.9 (examples, checks, comptime and constants are evaluated),
spec/tree-sitter/ is a tree-sitter port of the grammar checked against
the LALR(1) tables of section 3, and grammar-level random programs are checked by
rce-fuzz (spec/checker/). The production compiler has
not been built from this document yet. Changes made while mechanizing are
listed in 9.1 to 9.4. Draft 0.4 follows the language review in
spec/LANGUAGE-REVIEW.md; draft 0.5 applies the changes that review
proposed and draft 0.4 deferred (9.4).
RCE is defined by this document. A program is a text; its meaning is a Form P = (S, E, δ, D, λ) (section 6). Runtimes, emitters, harnesses and editors are not part of the language: they are implementations, and an implementation conforms when it accepts exactly the programs this document accepts and gives each one the meaning this document gives it.
Document status. This specification is the only normative text.
SURFACE.md (the native surface design) and FORM.md (the compiler
notes) are informative: two normative texts with two grammars could
disagree, and only one of them is checked by machine. Their programs
must still be accepted by the reference checker. The Form signature is
6.1.
The normative grammar is section 3, and it is also the machine-readable one:
rce-spec-check (in spec/checker/, Rust only) reads the EBNF of section 3
from book/03-syntax.md, builds its LALR(1) tables and fails on any
shift/reduce or reduce/reduce conflict, then parses every program in
spec/examples/ and requires every program in spec/examples/reject/ to be
refused, by the LALR(1) tables, the Rust parser and the tree-sitter port
alike, then runs rce-check over the same files (all examples together
form one program and must be accepted; the 12 syntax rejects, the 48
programs in spec/examples/ill_typed/ and the 16 in
spec/examples/inadmissible/ must be refused). Current result (draft 0.5): 0 conflicts
(100 rules, 472 productions, 932 states); grammar 51/51 accepted, 12/12
refused; checker 51/51 accepted, 12/12 and 64/64 refused (16 of them only by
W-INT-1, W-CT-1 or W-LEX-3). Until 2026-10-12 the same grammar was kept as
spec/rce.lark and checked with Lark (0 conflicts, 533 rules in Lark's
expansion); that file is retired.
rce-fuzz N SEED generates random type-directed programs from the
grammar's productions, with targeted near-misses. 100,000-program run
(8 parts × 12,500, seeds 1001–1008, spec/fuzz/RESULTS.md, with the former
Python generator and Lark): all 100,000
parsed by LALR(1), exactly one Earley parse each, all accepted by
rce-check; 516,012/516,012 rule near-misses and 392,362/392,362 syntax
near-misses refused; 0 failures. That run used the draft 0.4 generator.
From draft 0.5 the generator also covers extern, arena bound, structural
recursion, f32, lane-wise arrays, device regions, byte text, u64, select,
linear structs, LOOP_LIMIT and iterators; a 1,000-program run (seed 2026)
of it has 0 failures. The Rust generator, with the section-3 LALR(1)
tables as a third parser: 1,000 programs (seed 7), 0 failures, tree-sitter
and LALR(1) agree on all 4,977 syntax mutants.
Which version this is. This notebook shows specification draft 0.7, generated from commit 49fa9af of the RCE source. Public rce main (e416fd0) is at draft 0.9, which this notebook does not show yet; there is one language, the specification at one commit (2.7). The public repository states theorems T1 to T56, with 58 Lean modules and 59 example programs (12 syntax rejects, 48 ill-typed and 16 inadmissible programs are refused). Where a chapter quotes a count from an earlier draft, such as the draft 0.5 grammar result in the overview, it describes that draft. Draft 0.9 is described in the specification in the repository, not in these chapters. Counts come from src/data/rce-facts.json.
Chapters
Read them in order. Each chapter opens in plain words, then gives the exact rules. Formal grammar and typing rules sit in cells you can open and close. Every code cell can be edited and run.
- 00RCE Language Specification, draft 0.7: Overview
In the overview's tiny example, what is the name of the event?
- 011. Notation and conformance
In the grammar notation, what does a Repetition `{ ... }` mean, in the spec's words?
- 022. Lexical grammar
Which code point is the horizontal tab, as written in this section?
- 033. Syntactic grammar
Which numbered resolution rule in 3.11 covers `send`? (for example R1)
- 044. Programs, names and scope
What is the outermost scope called? (one word)
- 055. Static semantics
What is the name of the example kind used to illustrate error sets?
- 065 (continued). Static semantics: regions, effects and extensions
What kind of channel does a capacity of 0 give? (one word)
- 076. Dynamic semantics: the mapping into the Form
Which JavaScript function is named for rounding to binary32?
- 086 (continued). Dynamic semantics: steps, loops and concurrency
Name-free hashing uses indices named after which logician? (two words)
- 097. Well-formedness: what is refused at entry
Which rule refuses two unguarded steps in one region whose patterns overlap?
- 108. Theorems to prove
What is the deep embedding of the emitted Rust subset called?
- 119. Design decisions for review
The decisions list says it decides gaps in which file?
- 1210. Tooling: the `rce` command and the language server
Which JSON-RPC error code does the language server return for a request it does not know? (a number)
- 13References
Who wrote "Communicating Sequential Processes"? (surname)
- 14Appendix C. Draft 0.6 and 0.6b concurrency (normative for version 0.6 and 0.7 modules)
How many words does a version 0.6 module reserve in addition to the 0.5 keywords? (a number)
- 15Appendix D. The engine profile: handler specs and fits (normative)
Which compiled node id does `deliverable D1` become? (for example role_R1)
- 16Appendix E. The host contract (normative)
Which fcntl command is the append barrier on macOS? (for example F_SETFL)
Programs and the reading record
- All 130 example programs: the accepted ones, and every syntax reject, ill-typed and inadmissible program with its expected refusal.
- Read protocol: how a reader, human or AI agent, shows it read each chapter, using the chapter fingerprints and read-receipt questions.
Built from spec commit 49fa9af. Code cells run the reference checker rce-check, written in Rust and compiled to WebAssembly, inside your browser; nothing is sent to a server. Read-aloud uses the Kokoro-82M model (Apache-2.0), served from this site and run in your browser.