Common Lisp is a multi-paradigm, dynamically typed, general-purpose programming language and the ANSI-standardized dialect of the Lisp family. It was created by a committee in the early 1980s as a unification of several diverging Lisp dialects then in use across DARPA-funded AI laboratories, and it became an American National Standard, ANSI X3.226-1994 (now INCITS 226-1994), in December 1994.[1][2]
Common Lisp is best known for four things: a powerful macro system rooted in homoiconicity, a built-in object system called CLOS with multiple dispatch and a metaobject protocol, a condition and restart system more flexible than ordinary exception handling, and an unusually large standard with about a thousand symbols. It was the dominant language of symbolic AI research from the late 1980s through the early 1990s, and it remains in active use in computer algebra, planning systems, commercial scheduling software, and a small but committed open-source community.[3][4]
Common Lisp was designed for production AI work. Standardization was funded in part by DARPA so AI projects spread across MIT, CMU, Stanford, BBN, and the Lisp machine vendors could share code. After the AI Winter the language lost mainstream momentum, but it left a deep mark on later languages: Dylan, Clojure, and Julia all borrow heavily from Common Lisp, and Python's metaclass system traces its lineage to the CLOS metaobject protocol.[5][6]
By the end of the 1970s the Lisp family had fragmented into more than a dozen major dialects, none portable to the others. Significant Lisps in active use included MacLisp at MIT, Interlisp at Xerox PARC and BBN, Lisp Machine Lisp and Zetalisp at MIT and Symbolics, Spice Lisp at CMU, NIL at MIT, Standard Lisp at Utah, Franz Lisp at UC Berkeley, and Portable Standard Lisp. A program written in MacLisp would not load into Interlisp without substantial rewriting, and the cost of this fragmentation fell on DARPA, which funded most of the AI research being done across these systems.[1][7]
In April 1981 a meeting at Carnegie Mellon, organized by Scott Fahlman of CMU's Spice Lisp project and attended by representatives from MIT, Stanford, Symbolics, Lisp Machines Inc., DEC, and Bell Labs, set out to define a common dialect that would unify MacLisp-derived Lisps. Participants wanted a Lisp portable across stock hardware, suitable for large AI applications, and not so minimal that it would force everyone to reinvent libraries.[1][7][8]
The initial design effort was carried out almost entirely by electronic mail over the ARPAnet. The technical core included Guy Steele of Tartan Labs, Fahlman, Daniel Weinreb and David Moon of Symbolics, and Richard Gabriel of Lawrence Livermore (later Lucid). The first concrete artifact was the book Common Lisp the Language, written by Steele with the assistance of Fahlman, Gabriel, Moon, and Weinreb, published by Digital Press in 1984. The 465-page volume, known as CLtL1, was distilled from the committee's email archives and functioned as the de facto standard for the rest of the decade. It specified lambda lists with required, optional, rest, and keyword parameters; the package system; sequences; defstruct; multiple values; the printer and reader; format strings; and a numeric tower with bignums, ratios, and complex numbers. It did not yet specify an object system, a condition system, or a foreign function interface.[1][9]
During 1986 to 1988 a separate working group developed the Common Lisp Object System. The specification by Bobrow, DeMichiel, Richard Gabriel, Sonya Keene, Gregor Kiczales, and David Moon appeared as a special issue of SIGPLAN Notices in September 1988. CLOS borrowed from the Lisp Machine Lisp Flavors system and from CommonLoops, introducing multiple dispatch, multiple inheritance, and method combination.[10] The metaobject protocol (MOP) was specified later in The Art of the Metaobject Protocol by Kiczales, Jim des Rivieres, and Bobrow (MIT Press, 1991), exposing CLOS as itself a CLOS program so users can extend the object system through subclassing.[11]
A condition system designed by Kent Pitman replaced the older error-handling mechanism. Conditions are CLOS objects; restarts are named recovery options that the signaling code makes available to handlers further up the stack. Handlers can choose among published restarts without unwinding, an idea that distinguishes Common Lisp's handling from C++ and Java exceptions.[3] A second edition, CLtL2, by Steele appeared in 1990 at 1029 pages, documenting committee progress including CLOS, conditions, LOOP, and pretty printing.[12]
Formal standardization was conducted by ANSI subcommittee X3J13. The final standard was approved on December 8, 1994, as ANSI X3.226-1994, later redesignated INCITS 226-1994. With CLOS included, Common Lisp became the first object-oriented language to receive an ANSI standard. It was reissued without change in 2004 as INCITS 226:1994(R2004). A hyperlinked version called the Common Lisp HyperSpec, edited by Pitman and published by Harlequin (later LispWorks) in 1996, is freely available online and is the reference most working programmers consult.[2][13][14]
Common Lisp is multi-paradigm. It supports imperative code with assignments and loops, functional code with first-class functions and closures, object-oriented code through CLOS, and declarative styles through macros. The language defines about 25 special operators, around 1000 standard symbols, and a deep numeric tower.[3][14]
Dynamic typing. Values carry their type at runtime; the same variable can hold an integer, a string, a function, or a hash table. Optional type declarations via declare and the let compilers such as SBCL omit runtime type checks and generate native machine code competitive with C on numeric kernels.[15]
First-class functions and lexical closures. Functions are values that can be passed to and returned from other functions and stored in data structures. The lambda form constructs anonymous functions that close over their lexical environment. Common Lisp uses lexical scope by default for local bindings, with optional dynamic scope through variables declared special.[3]
Multi-namespace (Lisp-2). Common Lisp keeps function bindings and value bindings in separate namespaces, so the symbol list can name both a function and a variable in the same scope. This Lisp-2 design was inherited from MacLisp; to call a function held in a variable, programmers use funcall or apply. The Lisp-2 question was the most contentious split between Common Lisp and Scheme, which took the Lisp-1 path with a single namespace.[16]
Symbol packages. Symbols are interned in packages, namespaces that prevent name collisions. The standard ships COMMON-LISP, KEYWORD, and COMMON-LISP-USER.[3]
Conditions and restarts. When a function detects an error, it signals a condition object. Handlers established by handler-case or handler-bind higher up the stack inspect the condition and either return a value, abort, or invoke one of the named restarts that the signaling code published. The system separates policy from the mechanics of recovery, and it lets interactive debuggers offer restarts at the REPL.[3]
Macros and parameter forms. defmacro defines compile-time procedures that take s-expressions and return s-expressions. Reader macros extend syntax. Compiler macros provide optimization hooks. Lambda lists declare required parameters and then &optional, &rest, &key, and &aux sections; keyword arguments are matched by self-quoting symbols at the call site.[3][14]
Generic functions. CLOS adds defgeneric and defmethod, replacing the message-passing model with multimethods. A generic function dispatches on the runtime classes of all required arguments; there is no privileged "receiver" as in Java or C++.[10]
Tail-call optimization and GC. The standard does not require tail-call optimization, in deliberate contrast with Scheme. Most production implementations optimize tail calls in compiled code, but programmers cannot rely on it portably; the idiom for unbounded iteration is loop, do, or dolist. The standard does require automatic garbage collection; SBCL and CCL use generational copying collectors.[3][15]
CLOS is the object-oriented layer of the standard, designed during 1986 to 1988 by Bobrow, DeMichiel, Richard Gabriel, Keene, Gregor Kiczales, and David Moon, incorporated into CLtL2 in 1990, and finalized in the 1994 ANSI standard. It differs from object systems familiar from C++, Java, or Python in several important ways.[10][14]
Multiple dispatch. A method belongs to a generic function rather than to a class. When a generic function is called, the system selects applicable methods by matching the runtime classes of every required argument against the parameter specializers, then orders them by the class precedence list. There is no "this" pointer; binary methods like collide can dispatch on both arguments equally.[10]
Multiple inheritance with class precedence list. A class can name several direct superclasses. A linearization algorithm, similar to but predating Python's C3, computes a class precedence list (CPL) that orders the class and all ancestors. Slot inheritance, method ordering, and slot-value lookup all follow the CPL.[10][14]
Method combination. Programmers can write :before, :after, and :around methods alongside primary methods. Standard method combination runs all :before methods (most-specific first), then the most-specific primary method (which may call call-next-method), then all :after methods; :around methods wrap the entire call. Other built-in combinations (progn, +, list, and, or) and user-defined combinations let programmers customize dispatch.[10]
Metaobject Protocol. Kiczales and colleagues defined the metaobject protocol as a meta-level architecture for CLOS itself. Classes, generic functions, and methods are themselves CLOS objects of metaclasses (standard-class, standard-generic-function, standard-method). By subclassing metaobject classes and specializing protocol methods such as compute-applicable-methods, users can extend the object system without forking the implementation. The MOP is the conceptual ancestor of aspect-oriented programming and influenced metaclasses in Python.[11]
A minimal CLOS example:
(defclass point ()
((x :initarg :x :accessor x)
(y :initarg :y :accessor y)))
(defclass colored-point (point)
((color :initarg :color :accessor color)))
(defgeneric distance (a b))
(defmethod distance ((a point) (b point))
(sqrt (+ (expt (- (x a) (x b)) 2)
(expt (- (y a) (y b)) 2))))
(defmethod distance :around ((a colored-point) (b colored-point))
(format t "comparing colored points~%")
(call-next-method))
Common Lisp's macro facility is the feature most often cited as the language's defining advantage. Because every Lisp program is also a Lisp data structure (an s-expression), macros are ordinary functions from s-expressions to s-expressions, run at compile time, whose output the compiler sees in place of the call site. This homoiconicity has been a feature of Lisp since 1958.[3][17]
A defmacro form names a macro, gives it a destructuring lambda list, and provides a body that returns a transformed form. Templates are written with the backquote (`) reader macro: , splices a value and ,@ splices list elements. The reader is extensible via set-macro-character, so libraries can ship custom syntax (infix arithmetic, regex literals) without modifying the host. Common Lisp also offers define-symbol-macro and define-compiler-macro for optimization rewrites.
Common Lisp macros are not hygienic in the strict sense of Scheme's syntax-rules. Programmers avoid variable capture using gensym to generate unique symbols. The cost is real but small, and the gain is greater expressive power, since macros can deliberately introduce names user code refers to ("anaphoric" macros).
A simple when macro and an anaphoric aif that binds the test result to it:
(defmacro my-when (test &body body)
`(if ,test (progn ,@body) nil))
(defmacro aif (test then &optional else)
`(let ((it ,test))
(if it ,then ,else)))
Books devoted to Common Lisp macros include Paul Graham's On Lisp (1993) and Doug Hoyte's Let Over Lambda (2008).[17]
Common Lisp has more than a dozen serious implementations.
| Implementation | License | Notes |
|---|---|---|
| SBCL (Steel Bank Common Lisp) | Public domain / BSD | Forked from CMUCL in 1999; fastest open-source CL; multi-platform native compiler. |
| Clozure CL (CCL) | Apache 2.0 | Descendant of Macintosh Common Lisp; x86-64 and Apple Silicon. |
| CLISP | GPL | Bytecode interpreter; cross-platform; once the standard GNU CL. |
| ECL (Embeddable Common Lisp) | LGPL | Compiles via C; embeddable in C/C++ applications. |
| ABCL (Armed Bear Common Lisp) | GPL | Targets the JVM; can call Java directly. |
| GCL (GNU Common Lisp) | LGPL | Descendant of Kyoto CL; used historically by Maxima and Axiom. |
| Allegro CL | Commercial | Franz Inc., 1984; AllegroGraph triplestore. |
| LispWorks | Commercial | Cross-platform IDE; CAPI GUI toolkit. |
| CMUCL | Public domain | CMU Spice Lisp project; SBCL forked from this. |
| Symbolics Open Genera | Commercial | Lisp Machine OS as VM on Alpha and x86. |
| Lucid Common Lisp | Discontinued | Major commercial CL of the 1980s; vendor closed 1994. |
SBCL is the de facto reference for open-source work in the 2020s. Allegro CL and LispWorks are the surviving major commercial vendors.[15]
Common Lisp inherited the AI research community of MacLisp, Lisp Machine Lisp, and Interlisp; through the 1980s essentially every DARPA-funded AI lab moved to it. Major systems include:
Common Lisp lost ground through the 1990s as Lisp machines collapsed and commercial seats remained expensive. Grammarly and several smaller firms migrated away in the 2010s, citing hiring difficulty.[22]
Common Lisp's library ecosystem is small compared to Python or JavaScript but mature.
| Library | Purpose | Notes |
|---|---|---|
| Quicklisp | Package manager | Zach Beane, 2010; de facto installer. |
| ASDF | Build system | Another System Definition Facility. |
| Bordeaux Threads | Threading | Wraps platform-specific threading APIs. |
| CL-PPCRE | Regex | Perl-compatible regex by Edi Weitz. |
| Hunchentoot | Web server | Used in production CL web stacks. |
| Clack / Lack | Web abstraction | Rack/WSGI-style middleware layer. |
| CL-WHO | HTML generation | Macro-based HTML templating. |
| Parenscript | JS compilation | Translates CL-like code into JavaScript. |
| CFFI | FFI | Portable C interop. |
| Ironclad | Cryptography | Hashes, ciphers, MACs in pure CL. |
| Alexandria | Utilities | Standard "missing" utility library. |
Standardization went through three phases. The 1981 to 1984 design phase produced CLtL1. The 1986 to 1990 expansion phase added CLOS, conditions, and LOOP and produced CLtL2. The ANSI phase, conducted by subcommittee X3J13, produced ANSI X3.226-1994 ratified on December 8, 1994. X3J13's voting members included Steele, Weinreb, Moon, Fahlman, Gabriel, Pitman, Larry Masinter, Kim Barrett, William Clinger, Linda DeMichiel, Sandra Loosemore, Jon L White, Kiczales, and Pavel Curtis. Members included Apple, Bell Labs, DEC, Franz Inc., Harlequin, IBM, Lucid, MIT, Symbolics, Tartan Labs, Texas Instruments, and Xerox.[1][2][13]
The Evolution of Lisp by Gabriel and Steele (1993, ACM HOPL-II) is a candid history documenting the trade-offs behind the Lisp-2 design, the package system, and the absence of mandated tail calls.[1] No formal successor standard has appeared since 1994. Informal extensions include SLIME for editor integration, MOP support through closer-to-mop, and ASDF 3's package-inferred-system, but the language has been ANSI-frozen for three decades.
Common Lisp is no longer a mainstream production language but is alive in several niches. Maxima, the open-source successor of MACSYMA, continues active development on GCL and SBCL. The ACL2 theorem prover, used to verify floating-point hardware at AMD and Centaur, is a Common Lisp program built on GCL.[25] Research groups use Common Lisp for robot control, including the CRAM framework at Bremen. The /r/lisp community, European Lisp Symposium, and International Lisp Conference are the main meeting points.
Peter Seibel's Practical Common Lisp (Apress 2005), free online, is the standard modern introduction. Older books still in use include Paul Graham's ANSI Common Lisp (1995) and On Lisp (1993), Conrad Barski's Land of Lisp (2010), and Edi Weitz's Common Lisp Recipes (2015). Peter Norvig's Paradigms of AI Programming (1991) remains the canonical worked example. Graham's essays "Beating the Averages" (2003) and "Revenge of the Nerds" (2002) reignited startup interest, citing his experience using Common Lisp at Viaweb. The community is small: Common Lisp jobs number in the low hundreds globally, but salaries are high and codebases are unusually long-lived.[26][27][28]
Common Lisp's design ideas appear, sometimes unaltered, in several later languages.
loop-style sequence operations, and macros. Clojure innovates with persistent immutable data structures and software transactional memory, but the surface syntax and metaprogramming model are recognizably Common Lisp's.A small program that exercises defun, defclass, generic functions, multiple dispatch, and a macro:
(defclass shape () ())
(defclass rectangle (shape)
((width :initarg :width :accessor width)
(height :initarg :height :accessor height)))
(defclass circle (shape)
((radius :initarg :radius :accessor radius)))
(defgeneric area (s))
(defmethod area ((s rectangle))
(* (width s) (height s)))
(defmethod area ((s circle))
(* pi (expt (radius s) 2)))
(defgeneric overlaps-p (a b))
(defmethod overlaps-p ((a circle) (b circle))
(format t "two circles~%"))
(defmethod overlaps-p ((a rectangle) (b circle))
(format t "rect and circle~%"))
(defmacro with-area ((var shape) &body body)
`(let ((,var (area ,shape))) ,@body))
(defun report (s)
(with-area (a s)
(format t "~A area ~,2F~%" (class-name (class-of s)) a)))
The example shows three constructs that set Common Lisp apart from mainstream languages: methods that dispatch on more than one argument, classes defined separately from generic functions, and macros that take a block of body code.