The blue runtime — one definition of what a blue program runs against.
Before this crate existed, every consumer hand-rolled its own
Interpreter::new() + install_primitives(...) pair — three of them, in
three crates — and they had silently drifted: none of them loaded the Lisp
stdlib. So 6 % 3 lowered correctly to (mod 6 3), mod was genuinely
defined, and the program still died with unbound symbol: mod, because
the definition lived in a stdlib nobody loaded.
That is the duplication tax in its usual shape: the bug is not in any one copy, it is in there being copies. One function now owns the answer.
Layers
A blue interpreter is built in two layers, and both are required:
- Rust primitives — arithmetic, comparison, list ops, I/O.
- The full tatara stdlib — primitives, higher-order functions
(
map/filter/fold), maps, channels, fibers, type-check, and everything tatara defines in tatara-lisp itself (mod,rem,first,inc,even?, the actor and transducer helpers, …). Loading it is not optional garnish: blue's own operator lowering depends on it. - blue's own core ([
stdlib]) — strings and number conversion, which tatara-lisp does not have in any form. A Ruby-surface language withoutlengthorupcaseis not usable, and the semantics are Ruby's (characters, not bytes), which is why they are blue's and not the substrate's.