Skip to content

mal — Make a Lisp

mal (“Make a Lisp”) is the canonical 11-step guided tutorial for building a Lisp interpreter from scratch, structured as an incremental sequence of steps where each step adds one capability (step 0 = REPL skeleton; step 1 = read/print; step 2 = eval; step 3 = environments; step 4 = if/fn/do; step 5 = TCO; step 6 = files & eval; step 7 = quoting; step 8 = macros; step 9 = try & catch; step A = mal-in-mal self-hosting). The project is famous for its breadth: 89 distinct host-language implementations exist (C, C++, Rust, Go, Python, Ruby, Lua, JavaScript, Common Lisp, Scheme, Clojure, Haskell, OCaml, Erlang, Elixir, Forth, Tcl, COBOL, MAL itself, and many more), and the 11-step structure is the same across all of them — which means mal is the lingua-franca curriculum for “implement a small Lisp in language X.”

For KN-86 it is the single most important blueprint reference for the embedded Lisp scripting layer recommended in this batch’s synthesis. Even though KN-86’s chosen runtime is Fe (per ADR-0001 / ADR-0004) rather than a from-scratch implementation, the step-by-step pedagogy of mal is the right reference for documenting how KN-86’s Lisp runtime maps to a Lisp, and for any case where KN-86 wants to layer additional semantics on top of Fe (a macro system, a try / catch, a quasi-quote).

  • mal is the documentation reference for ADR-0001 / ADR-0004 / ADR-0005’s prior-art sections. “The pattern we’re committing to — a small embedded Lisp authored against a stable C-ABI FFI — is the same pattern mal demonstrates across 89 host languages, including in a way directly relevant to embedded contexts.” Worth a one-paragraph cite in each.
  • The 11-step structure is the right scaffold for KN-86’s cart-authoring tutorial. When the cart-authoring SDK gets a tutorial pass, structuring it as “step 0 / step 1 / … / step N” mirroring mal’s incremental approach gives cart authors a known-good pedagogy. The KN-86 steps would be different (load a static glyph; respond to a key event; render a sparkline; persist save state; advance a mission phase; emit a CIPHER fragment; etc.) but the progressive disclosure of the model is the same.
  • Self-hosting (mal-in-mal) as the long-tail validation. mal’s final step is implementing mal in mal — proving the language is complete enough to express its own interpreter. For KN-86 the analog isn’t self-hosting (Fe is the runtime; the cart Lisp doesn’t implement Fe), but the principle of “express the runtime’s hardest behaviors as cart Lisp test cases” transfers. A cart that exercises every NoshAPI primitive in a reasonable composition is the closest KN-86 analog — and is a high-value acceptance-test cart for the runtime.
  • Macros as the step-8 capability. mal step 8 introduces macro definitions and macro expansion. KEC Lisp’s macro support matters because cart authors will want to extend the cart-authoring vocabulary. Worth confirming explicitly in Fe-on-KN-86 docs that macros are sanctioned and how they compose with NoshAPI (do macros expand at AOT-compile time or at cart-load time? open question worth answering in the cart-authoring grammar spec).
  • TCO (step 5) and TRY/CATCH (step 9) are the two semantic-richness gates. Tail-call optimization makes recursive cart logic safe; try/catch makes failure handling sane. Both are worth confirming as Fe-on-KN-86 capabilities and documenting in the cart-authoring grammar spec. (Fe ships TCO; try/catch worth confirming.)

No image downloaded — mal is a curriculum / source-code reference, not visual.

  • Direct cite candidate in ADR-0001 / ADR-0004 / ADR-0005 prior-art sections.
  • Cross-link build-your-own-lisp.md — the C-specific narrower-path equivalent. mal is the generalist “make a Lisp in any language” reference; BuildYourOwnLisp is the specialist “make a Lisp in C in <1000 lines” reference. Both are valuable; mal for breadth and self-hosting, BYOL for the focused-C-implementation reading.
  • Cross-link cl-termbox2.md — that entry is the integration story (how the Lisp reaches the terminal); mal is the language story (how the Lisp itself is built). Together they bracket the Lisp-on-the-deck architecture.
  • Cross-link Zork — the historical archetype. Zork was MDL (a 1970s MIT Lisp); mal is the modern pedagogical descendant of “let’s implement that”; KN-86’s KEC Lisp is the contemporary working version of the same lineage. The historical chain MDL → mal → Fe → KN-86 cart is real.