Appendices: Projects, Interview Questions, Cheat Sheet & Study Plan
Capstone projects, interview questions, a cross-dialect cheat sheet, Lisp for developers coming from other languages, and resources with a study plan.
Appendix A: Capstone Projects
Beginner: List Utilities Library. Implement map, filter, reduce, flatten, zip, range, take, and drop recursively in Scheme, with tests.
Beginner: Symbolic Calculator. Parse prefix expressions, evaluate them, and simplify algebraic expressions ((+ x 0) → x).
Intermediate: Symbolic Differentiator. Extend SICP's deriv with exponents, sin/cos, and simplification.
Intermediate: Text Adventure. Game state as association lists or maps, a command parser, and save/load via read/write of s-expressions.
Intermediate: Emacs Package. A minor mode with interactive commands, keybindings, customizable variables, and an ERT test suite.
Intermediate: Clojure Web API. Ring + Reitit + next.jdbc with immutable data transformations and a REPL-driven workflow.
Advanced: Your Own Lisp. Complete Modules 34–35: TCO, macros, strings, error handling, and a standard prelude written in your Lisp.
Advanced: Metacircular Evaluator Variants. Implement SICP's lazy evaluator and amb evaluator; solve logic puzzles with amb.
Advanced: miniKanren Puzzles. Implement miniKanren (or use a library) and solve Zebra/Einstein puzzles relationally.
Advanced: A DSL with Racket #lang. Build a custom language (e.g., a state-machine or config language) with its own reader and expander.
Advanced: Compiler. Follow Ghuloum's incremental approach to compile a Scheme subset to x86-64 or WebAssembly.
Comparative Project: implement the same program (e.g., a JSON parser or a Game of Life) in Scheme, Common Lisp, and Clojure, then write up the differences.
Appendix B: Interview Questions
What makes Lisp different from other languages? What is homoiconicity?
What is an s-expression? What is a cons cell? What are car and cdr?
What does quote do? What do quasiquote, unquote, and unquote-splicing do?
What's the difference between a function, a special form, and a macro?
Lisp-1 vs Lisp-2: what's the difference? Which dialects are which?
Explain lexical vs dynamic scope with an example.
What is a closure? Build a counter with one.
What is tail-call optimization? Which Lisps guarantee it? What does Clojure's recur do?
Explain eq?/eqv?/equal? (or eq/eql/equal/equalp).
What are hygienic macros? What is variable capture, and how does gensym help?
What is a continuation? What can call/cc implement?
What are streams/lazy sequences? How do you represent an infinite list?
What is the metacircular evaluator? Explain the eval/apply cycle.
How would you implement a Lisp interpreter? What are environments?
What is the Y combinator, and why does it matter?
Compare Scheme, Common Lisp, Clojure, and Emacs Lisp.
How does Clojure handle state and concurrency (atoms, refs, agents)?
What is REPL-driven development, and why is it productive?
How do association lists, property lists, and hash tables differ?
Why was garbage collection invented for Lisp? Describe mark-and-sweep.
Write flatten for arbitrarily nested lists.
Write deep-reverse that reverses a list and all its sublists.
Implement my-map and my-filter with recursion, then with fold.
Write a swap! macro (hygienic in Scheme, gensym-based in CL).
Write a while loop macro.
Implement a memoize higher-order function using a hash table.
Write the power set of a list.
Evaluate a prefix arithmetic expression given as a list.
Appendix C: Cross-Dialect Cheat Sheet
Scheme / Racket (define x 1) (defparameter *x* 1) (defvar x 1) (define (f a)...) (defun f (a)...) (defn f [a]...) (lambda (x)...) (fn [x]...) / #(...) (let ((x 1))...) (let [x 1]...) (def x 2) / atoms (if c a b), cond + else (if c a b), cond + t (if c a b), cond + :else true / false, nil Call function value (funcall f x) (apply f lst) (apply f coll) (mapcar f lst) (map f coll) (filter p lst) (remove-if-not p lst) (filter p coll) (seq-filter p lst) (foldl f init lst) (reduce f lst) (reduce f coll) (seq-reduce f lst init) (string-append a b) (concatenate 'string a b) (concat a b) (format t "~a" x) (message "%s" x) named let, for loop, dolist, dotimes loop/recur, doseq dolist, while with-handlers / guard ; and #|...|# ; and (comment...)
Appendix D: Lisp for Other Developers
Python / JavaScript / Java Infix with precedence (+ a (* b c)) if (c) { a } else { b }
(if c a b) (an expression returning a value) (define x 5) / (let ((x 5))...)
'(1 2 3) / (list 1 2 3) / [1 2 3] (Clojure) alist, hash table, {:a 1} (Clojure) lambda x: x * 2 / x => x * 2 (lambda (x) (* x 2)) / #(* % 2) for x in xs:
(for-each...), (dolist...), (doseq...) Decorators / annotations Macros (much more powerful) (eval '(code)): code is already data Closures, CLOS, protocols
Conditions and restarts (CL), guard, try Continuations, lazy sequences, streams Key gotchas:
Everything is an expression, and almost everything returns a value.
Parentheses are significant: (f) calls f; f is the value; ((f)) calls the result of calling f.
'(1 2 3) is a literal constant; don't mutate quoted literals.
In Common Lisp and Emacs Lisp, the empty list and false are the same thing (nil).
Don't fight the parentheses: use an editor with structural editing and rainbow parens.
Appendix E: Resources and Study Plan
*Structure and Interpretation of Computer Programs* (SICP, Abelson & Sussman): free online; the classic
*How to Design Programs* (HtDP, Felleisen et al.): free online, Racket
*The Little Schemer*, *The Seasoned Schemer*, *The Reasoned Schemer* (Friedman et al.)
*The Scheme Programming Language* (Dybvig): free online *Practical Common Lisp* (Seibel): free online
*Paradigms of Artificial Intelligence Programming* (PAIP, Norvig): free online, Common Lisp *On Lisp* (Graham): free online; macros
*Let Over Lambda* (Hoyte): advanced macros *Land of Lisp* (Barski), *Realm of Racket*
*Clojure for the Brave and True* (Higginbotham): free online
*Programming Clojure*, *The Joy of Clojure*, *Getting Clojure*
*An Introduction to Programming in Emacs Lisp* (GNU, free; built into Emacs)
*Lisp in Small Pieces* (Queinnec): implementing Lisp *Beautiful Racket* (Butterick): free online; building languages
Make a Lisp (mal): github.com/kanaka/mal Peter Norvig's *(How to Write a (Lisp) Interpreter (in Python))*
SICP video lectures (MIT 6.001, 1986), Racket docs, CLiki (Common Lisp wiki), ClojureDocs, the Emacs manual
Communities: r/lisp, r/scheme, r/Racket, r/Clojure, r/emacs, the Lisp Discord, Clojurians Slack, Racket Discourse, the Common Lisp Cookbook 11-Week Study Plan
History, setup, s-expressions, evaluation and quote Cons cells, functions, conditionals, recursion
Lambda and higher-order functions, closures, symbols, maps Iteration, strings and I/O, homoiconicity, macros Scheme and Racket in depth
Common Lisp overview, Clojure, Emacs Lisp, other Lisps, comparison
Tail calls, continuations, macro hygiene, streams Lambda calculus, symbolic programming, DSLs, logic programming, closure objects
Metacircular evaluator, Python interpreter, extensions Compilation, garbage collection, concurrency, web 40–42 + Capstone Industry, tooling, history, project
Final tip: Lisp rewards depth. Work through SICP's exercises, build your own interpreter, and write a macro that changes how you think about code. Then pick one dialect (Racket for learning, Clojure for modern backends, Common Lisp for performance and longevity, Emacs Lisp for your editor) and build something real. (Happy (hacking)) 🎉