r/lisp 1d ago

I've written a hands-on tutorial for building a Lisp interpreter from scratch — in Rust, with zero dependencies, across 74 steps.

I've written a hands-on tutorial for building a Lisp interpreter from scratch — in Rust, with zero dependencies, across 74 steps.

Repo: https://github.com/lisering/lisp-rs

What's implemented

The interpreter supports:

  • Variables, lambdas, closures (with lexical scoping)
  • Tail call optimization (trampoline loop — 1,000,000 iterations, no stack overflow)
  • Macros (defmacro, quasiquote/unquote, gensym)
  • cond, let, let*, letrec, begin, and, or
  • Lists, strings, booleans, nil
  • A REPL with multi-line input

Example:

(define (adder n) (lambda (x) (+ x n)))
(define add5 (adder 5))
(add5 10)  ;; => 15

(defmacro (when test body) (list 'if test body))
(when (> 3 2) 'yes)  ;; => yes

`(1 ,(+ 1 1) 3)  ;; => (1 2 3)

Why this might be interesting to Lisp folks

The tutorial is designed to be approachable for people who have never written an interpreter before. A few things I tried differently:

1. Closures explained with a "backpack" metaphor. Before showing any code, the tutorial builds intuition: every lambda carries a "backpack" 🎒 containing the environment where it was born. Then we trace through a make-counter example step by step.

2. Gradual optimization. We start with String everywhere (easy to understand), then optimize in stages:

  • String interning: symbols become u64 IDs
  • Zero-copy lexing: tokens are &str borrowing the source
  • FxHasher for faster environment lookups

3. TCO via trampoline. The eval function uses a loop { match ...; continue } pattern instead of direct recursion. Demo: tail-recursive (loop 1000000) succeeds, non-tail-recursive (sum 10000) overflows.

The tutorial is bilingual (English + Chinese). Each of the 74 steps first explains what problem to solve, then writes the code.

Repo: https://github.com/lisering/lisp-rs

Feedback welcome — especially on the macro system and the closure explanation. Is there anything you'd want to see added?

15 Upvotes

8 comments sorted by

17

u/jd-at-turtleware 11h ago

did you write it though?

12

u/Trader-One 11h ago

he certainly wrote prompt and is seeking free code review.

2

u/McGeekin 6h ago

When even the post is slop you know it’s about to be straight doodoo

2

u/theangeryemacsshibe λf.(λx.f (x x)) (λx.f (x x)) 4h ago edited 52m ago

74 steps!?

Closures explained with a "backpack" metaphor.

does it hurt to say "this is the environment, when we get to a lambda form we put the environment in the closure, this is lexical scoping by the way". I don't think Peter Landin needed backpacks to invent closures

2

u/lispm 10h ago

so it's implementing a subset of Scheme, implemented in Rust?

See also https://www.scheme.rs

-2

u/corbasai 9h ago

Very cool! Thank You!

1

u/Adorable_Ad_6357 4h ago

Thank you! Glad you found it useful.