History, Implementations and Best Practices
55.1 History
Lisp and LISP 1.5 (McCarthy) MacLisp, Interlisp, Lisp Machine Lisp, Scheme
ARPA-sponsored effort to unify Lisp dialects begins *Common Lisp the Language* (CLtL1, Guy Steele)
X3J13 committee; CLOS designed (based on Flavors and CommonLoops) CLtL2 (second edition)
ANSI X3.226-1994: the Common Lisp standard; CLOS made it the first ANSI-standardized object-oriented language *The Art of the Metaobject Protocol* *On Lisp* (Graham) SBCL forks from CMUCL *Practical Common Lisp* (Seibel)
SBCL monthly releases, Coalton, Clasp, CLOG, ocicl, Lem, Nyxt, a revived community
55.2 Best Practices
✅ Develop interactively: compile one form at a time, test at the REPL, keep the image running.
✅ Organize code into packages and ASDF systems. Pin dependencies for applications.
✅ Use defparameter for configuration and defvar for state that should survive reloads.
✅ Write docstrings; use check-type and condition types for robust APIs.
✅ Use CLOS generic functions for extensible behavior and structures for simple fast records.
✅ Embrace the condition system: signal specific conditions, provide restarts in libraries, and decide policy at the top level.
✅ Measure before optimizing; add type declarations only in hot paths.
✅ Use Alexandria/Serapeum/UIOP instead of reinventing utilities.
✅ Write tests (FiveAM/Parachute) and run them in CI on more than one implementation.
❌ Mutating literal (quoted) data, or relying on destructive operations without using their results
❌ Using eval or intern on untrusted input; reading untrusted data with *read-eval* true
❌ Overusing macros where functions suffice; unhygienic macros that capture variables
❌ Global (safety 0): use it only locally in verified hot code
❌ Giant packages that :use many libraries (use package-local nicknames instead)
❌ Swallowing errors with broad ignore-errors