A Gentle Introduction, Four Lisps: One Book, Four Re-tellings

Table of Contents

1. One book, four Lisps

This is a point-in-time note, and the question is narrow: when you re-tell the same gentle introduction to symbolic computation in four Lisps, what does each one actually buy — the student reading it, and the maintainer keeping it green?

The artifact is Touretzky's A Gentle Introduction to Symbolic Computation (Touretzky 1990) — recursion, lists, closures, macros, code-as-data. It has been re-told four times, each a working repo with two passing gates on chapter one:

  • Common Lisp — the origin (the book's own dialect), verified end-to-end.
  • Clojure — a re-telling at roughly half the size.
  • Scheme (Guile) — the re-telling closest to the book.
  • Hy — Lisp on Python's runtime, the re-telling that drifts furthest.

The four implementations already exist; they are the evidence. This is the same move as reading four type disciplines off one reversible-transform tool (one tool, four ways) — one artifact, N lenses.

2. One divide, and most of the story

Chapter one defines average — Touretzky's (/ (+ a b) 2) — and the helper half. Evaluate (half 5) in each:

Lisp (half 5) why
Common Lisp 5/2 rational — the numeric tower is intact
Clojure 5/2 exact Ratio
Scheme/Guile 5/2 exact rational
Hy 2.5 Python's float division — the tower is Python's

Three exact, one float. That single line is the thesis in miniature: the numeric tower is a language-family property, and Hy — Lisp syntax over Python's runtime — does not inherit it. Everything a Python-native reader gains (the ecosystem, familiarity) is paid for here, in the first arithmetic example, with a rounding the other three never do. Nothing about the parentheses tells you this; only running it does.

3. What each Lisp buys — read off the axes

axis Common Lisp Clojure Scheme (Guile) Hy (on Python)
numbers rational tower rationals + BigInt rational tower Python floats / ints
lists cons cells persistent vectors & lists cons cells Python list (no cons)
predicates evenp / -p even? / ? even? / ? ? mangles from Python
state setf / special vars atoms / refs / agents (rich) set! + lexical Python mutation
recursion stack; labels recur (TCO), lazy seqs tail calls (real TCO) Python recursion limit
macros defmacro + gensym defmacro + gensym (~#) hygienic syntax-rules defmacro → Python AST
test framework hand-rolled + loader clojure.test SRFI-64 Hy-native asserts
lint / static custom org checkers clj-kondo guild compile hyc compile
visibility tool built by hand (traces) Portal / FlowStorm / tap> REPL + ,trace hy2py (read the Python)
build org-tangle + ASDF/SBCL deps.edn + bb make + modules pyproject + hyc

Two read-offs fall out of the table.

For the student. Hy sells reach — "Lisp rides on the Python you already run" — and charges the numeric tower and cons cells for it; it is the on-ramp, not the destination. Guile sells fit — the SICP heartland (Abelson, Sussman, and Sussman 1996), nothing between the reader and the ideas, hygienic macros the origin can't teach. Clojure sells a state model — atoms, refs, and agents make the chapter Common Lisp couldn't (managed identity), and persistent data changes what "a list" even means. Common Lisp is the fullest and the heaviest onramp — the reference, not the recommendation.

For the maintainer. Read the bottom half of the table as a bill of materials. The Common Lisp companion hand-builds what the others get for free — an org tangle pipeline, an ASDF system per chapter, a (check) macro and a loader, two custom lint checkers, its own tracer. Each re-telling deletes that column and adopts the standard thing (clojure.test, SRFI-64, clj-kondo, Portal). The Clojure port came out at ~half the size, and the halving is entirely deleted ceremony, not cut material.

4. The method, and what stays constant

Same shape as the type-systems note: hold the artifact fixed, vary one dimension, and the differences that survive are the ones that matter. Here the fixed artifact is a pedagogical arc and the varied dimension is the Lisp; there it was a codec and the type discipline.

What does not vary is the discipline. Every re-telling is built the same way: each unit is simultaneously something to read, something to run, and something that checks itself; two orthogonal gates (documents + code); one chapter at a time, green before moving on; verify by running, not reasoning. The mechanism of verification changes with the language — hand-rolled, clojure.test, SRFI-64, Hy asserts — but the act does not. That constancy is the point: a language buys you a numeric tower or a macro hygiene or a state model, but it does not buy you the assurance that your claims are true. You buy that by seeing them run, in whichever dialect (visibility is verification).

6. References

Abelson, Harold, Gerald Jay Sussman, and Julie Sussman. 1996. Structure and Interpretation of Computer Programs. 2nd ed. Cambridge, MA: MIT Press.
Hickey, Rich. 2020. “A History of Clojure.” Proceedings of the Acm on Programming Languages 4 (HOPL). https://doi.org/10.1145/3386321.
Touretzky, David S. 1990. Common Lisp: A Gentle Introduction to Symbolic Computation. Redwood City, CA: Benjamin/Cummings.