RFC-006: Language Choice for Law Execution Engine
Status: Proposed Date: 2025-01-26 Authors: regelrecht team
Context
The law execution engine requires a language that supports:
- Browser deployment: The engine must run in the frontend editor via WebAssembly (WASM)
- Deterministic execution: Legal requirement - identical inputs must always produce identical outputs
- Type safety: Schema conformance should be verifiable at compile time
- AI-aided development: The team uses an AI coding agent as primary development tool
A Python prototype exists (engine/) demonstrating the execution model. The question is which language to use for the production implementation.
Decision
Use Rust for the law execution engine.
Why
Benefits
| Requirement | How Rust Addresses It |
|---|---|
| WASM compilation | First-class support via wasm-pack and wasm-bindgen. Produces small, fast binaries. |
| Determinism | Compiler enforces: no implicit type coercion, no null exceptions, exhaustive pattern matching, precise integer types. |
| Type safety | Strong static types catch schema violations at compile time. Result and Option make error handling explicit. |
| AI-aided development | Type system provides actionable feedback loop: generate → compile → fix errors → repeat. |
Additional benefits:
- Memory safety without garbage collector (important for WASM performance)
- No runtime exceptions from null/undefined
- Pattern matching aligns well with rule-based logic
serdeprovides reliable YAML/JSON parsing with compile-time validation
Tradeoffs
| Tradeoff | Mitigation |
|---|---|
| Learning curve (ownership, borrowing, lifetimes) | AI assistance reduces friction; team can learn iteratively |
| Slower iteration (compile times) | Incremental compilation; WASM hot-reload tooling exists |
| More verbose than Python | Explicitness is a feature for legal code; reduces ambiguity |
| Smaller ecosystem than Python for data processing | Core requirements are well-supported |
Alternatives Considered
Alternative 1: Python (keep current prototype)
- Pro: Team knows it well, fast iteration, extensive ecosystem
- Pro: Pyodide enables WASM compilation
- Con: Pyodide adds 11MB+ runtime overhead to WASM bundle
- Con: Type safety is runtime-only (mypy/pyright are optional, not enforced)
- Con: Implicit type coercion can cause subtle bugs
- Why not: WASM bundle size and lack of compile-time guarantees are deal-breakers
Alternative 2: TypeScript
- Pro: Runs natively in browser, no WASM needed
- Pro: Good tooling, wide adoption
- Con: JavaScript runtime has type coercion issues (
"1" + 1 = "11") - Con: No compile-time exhaustiveness for pattern matching
- Con:
nullvsundefinedambiguity - Why not: Runtime type coercion undermines determinism guarantees
Alternative 3: Go
- Pro: Simple language, fast compilation
- Pro: WASM support via TinyGo
- Con: TinyGo WASM has limitations (no reflection, reduced stdlib)
- Con: Less expressive type system than Rust (no sum types, no pattern matching)
- Why not: Type system insufficiently expressive for rule logic
AI-Aided Development Assessment
Rust works well with AI code generation:
- Compiler as reviewer: Type errors provide specific, actionable feedback that AI can use to self-correct
- Pattern matching: AI generates idiomatic Rust with
matchexpressions for rule logic - Result handling: Explicit error types guide AI toward correct error handling
- No runtime surprises: If it compiles, many bug classes are eliminated
The generate → compile → fix cycle with Rust is faster than generate → run → debug with dynamic languages.
References
- wasm-pack - Rust WASM toolchain
- wasm-bindgen - JS interop
- Pyodide - Python in WASM (for size comparison)
- serde - Serialization framework
- Glossary of Dutch Legal Terms