Common Lisp
Common Lisp，縮寫為CL（不是組合邏輯的縮寫）是Lisp編程語言的一種方言，由ANSI INCITS 226-1994(R2004)（前身為ANSI X3.226-1994(R1999)），所定義的語言規範標準。Common Lisp HyperSpec是源自於ANSI Common Lisp標準的網頁超連結版本。
CL語言是為標準化和改良Maclisp而開發的後繼者。到20世紀80年代初，幾個工作群組已經在設計MacLisp各種後繼者，例如：Lisp Machine Lisp（又名 ZetaLisp），Spice Lisp，NIL和S-1 Lisp。CL是為了標準化和擴展此前眾多的MacLisp分支而開發，它本身並非具體的實作，而是對語言設立標準的規範。有數個實作符合Common Lisp規範，其中包括自由和開源軟件，以及商業化產品。CL支援了結構化、函數式和物件導向編程等範式。相对于各种嵌入在特定产品中的语言，如Emacs Lisp和AutoLISP，Common Lisp是一種用途廣泛的编程语言。不同於很多早期Lisp，Common Lisp如同Scheme，其中的變量是預設為詞法作用域的。
身為一種動態編程語言，它有助於進化和增量的軟件開發，並將其迭代編譯成高效的執行程序。這種增量開發通常是互動持續地改善，而不需中斷執行中的應用程序。它還支援在後期的分析和優化階段添加可選的型別註記與轉型，使編譯器產生更有效率的代碼。例如在硬體和實作的支援範圍內，codice_1能保存一個未封裝整數，允許比大整數或任意精度類型更高效率的運算。同樣地，在每個模組或函數的基礎上可聲明優化，指示編譯器要編譯成哪一類型的安全級別。
CL包含了支援多分派和方法組合的物件系統，縮寫為CLOS，它通常以元物件（Metaobject）協定來實現。
CL藉由標準功能進行擴展，例如Lisp宏（编译时期程序自身完成的代码重排（compile-time code rearrangement accomplished by the program itself））和阅读器宏（赋予用户自定义的語法以扩展具特殊意义的符号（extension of syntax to give special meaning to characters reserved for users for this purpose））。
CL為Maclisp和约翰·麦卡锡的原創Lisp提供了一些向後兼容性。這允許較舊的Lisp軟件移植到Common Lisp之上。
在1981年，ARPA管理者Bob Engelmore最初发起了关于Common Lisp的工作，开发一个单一的社群标准Lisp方言。大多数最初的语言设计是通过电子邮件完成的。在1982年，Guy L. Steele Jr.于1982年度LISP和函数式编程研讨会上首次给出了Common Lisp的概述。
在1984年，首个语言文档被出版为《》，第一版（也叫做CLtL1）。在1990年，第二版（也叫做CLtL2）出版了，它结合了在ANSI Common Lisp标准化过程中对语言做的很多变更：扩展的codice_2语法、Common Lisp对象系统、用于错误处理的条件系统、到精美打印的接口等等。但是CLtL2不描述最终的ANSI Common Lisp标准，因而不是ANSI Common Lisp的文档。在1994年，最终的ANSI Common Lisp标准出版了。自从出版之后标准就没有更新。对Common Lisp的各种扩展和改进（例如Unicode、并发、基于CLOS的IO）都由实现和函数库来提供。
Common Lisp是Lisp編程語族的一種方言; 它使用S-表达式來表示源碼和資料結構。函数调用、宏形式和基本形式都以列表來編寫，列表的第一项是函数名稱，如以下範例：
Common Lisp 擁有豐富的数据类别。
數值型別包括整數，分數，浮點數和複數。Common Lisp使用大數（bignums）來表示任意大小和精度的數值。 分數型別確切地代表分數，很多語言並不具備這種能力。Common Lisp會自動將數值轉換成適當的型別。有許多方式取捨數值，函數codice_3將參數四捨六入為最接近的整數，逢五則取偶整數。codice_4，codice_5和codice_6分別朝向零，向下或向上取整數。所有這些函數將捨去的小數當作次要值返回。
例如，codice_7產生 -3, 0.5；codice_8產生 -2，-0.5；codice_9得到 2,0.5；和codice_10得到 4，-0.5。
Common Lisp字元型別不限於ASCII字符，因為在ASCII出現前Lisp就已經存在了。大多數現代實現允許Unicode字元。
符號（Symbol）型別是Lisp語言共有的，而在其它語言中較少見。一個符號是個命名唯一的對象，它擁有幾個部份：名稱，值，函數，屬性列表（property list）和套件。其中，值單元和函數單元是最重要的。Lisp中的符號通常類似於其它語言中的標識符（identifier）用法：保存變量的值；然而還有很多種用途。一般來說，對一個符號求值時會得到以該符號為變量名稱的值，但也有例外：譬如在關鍵符套件中的符號，形如codice_11的符號值就是它本身（自我評估的，self-evaluating），而符號codice_12和codice_13則用於表示布爾邏輯值真與假。Common Lisp可設計容納符號的命名空間，稱為“套件”（package）。
Common Lisp的序列型別包括列表、向量、位元向量和字串。有許多函式可對應不同型別的序列進行操作。
CL如同所有Lisp方言，列表由點對（conses）組成，有時稱為cons單元、序偶或構對。一個點對是帶有兩個儲存槽的數據結構，分別稱為car和cdr。列表就是一條點對的串列，或只是空列表。每一個點對的CAR會參照列表的成員（可能是另一個列表）。而除了最後一個的CDR參照到codice_14值之外，其餘的CDR都會參照下一個點對。Conses也能輕易地實現樹和其它複雜的數據結構；儘管一般建議以結構體或是類別的實例來代替。利用點對能夠創建循環形的数据結構。
CL支援多維陣列，且如需要能動態地調整陣列大小。多維陣列常用於數學中的矩陣運算。向量就是一維陣列。陣列可載入任何型別（甚至於混合的型別）的成員，或只專用於特定某一型別的成員，例如由整數構成的位元向量。許多Lisp實作會根據特定型別，對陣列的操作函數進行優化。兩種特定型別的專用陣列是內建的：字串和位元向量。字串是由許多字元構成的向量，而位元向量是由許多位元構成的向量。
散列表儲存对象之間的關聯，任何物件都可以作為散列表的鍵或值。和陣列一樣，散列表可依需求自動調整其大小。
套件是一組符號的集合，主要用於將程序的個別部份區分命名空間。套件能匯出一些符號，將它們作為共用介面的某一部份，也可以匯入其它套件引用並概括承受其中的符號。
CL的結構體（Structures）類似於C語言的structs和Pascal的records，是一種任由使用者發揮的複雜数据結構定義，表示具有任意數量和任何型別的欄位（也叫做槽）。結構允許單一繼承。
類別（Class）在後期被整合進Common Lisp中，有些概念與結構體重疊，但類別提供了更多的動態特性和多重繼承（見 CLOS）。由類別創建的物件稱為實例。有個特殊情況是泛型（Generics）的雙重角色，泛型既是函數，也是類別的實例物件。
Common Lisp支援頭等函數（亦即函數可當成数据類型來處理）。例如編寫以其它函數當作一個函數的參數，或函數的傳回值也是函數，利用函數的結合來描述常用的操作。CL函式庫高度依賴於這樣的高階函數變換。舉例而言，codice_15函數可將關係運算子作為參數，並選用如何取鍵的函數作為參數。如此一來不但能對任何型別的数据排序，還能根據取用的鍵值對数据結構作排序。
對函數求值的模型非常簡單。當求值器遇到一個形式如codice_16時，那麼名稱為codice_17的符號會被假定是以下三種狀況之一：
如果codice_17符號是三者其中之一，則求值器判定它是個函數，找到此函數的定義內容，然後以從左到右的次序來評估參數codice_20的值，並且使用這些值進行運算，以函數定義中最後一個評估的結果作為傳回值。 宏codice_21用来定义函数。函数定义给出了函数名，参数名和函数体：
函数定义中可以包括“声明”，它可以指示编译器优化设置或参数的数据类型等。还可以在函数定义中包括“文档字符串”（docstring），Lisp系统用它们形成互動式文档：
匿名函数用codice_18表达式定义。Lisp编程频繁使用高阶函数，以匿名函数作为其参数的作法十分有效。
还有一些有关于函数定义和函数操作的运算符。如，操作符codice_23可以用来重新编译函数。（一些Lisp系统默认下在解释器里运行函数，除非指示编译它；其他Lisp系统在函数输入时即被编译。） codice_24宏用來定義泛化函數，而codice_25宏則用來定義方法。泛化函數是一些方法的集合。方法可依照CLOS標準類別、系統類別、結構類別或物件，以特定方式處理它們所使用的參數。許多型別都有相對應的系統類別。當呼叫泛化函數數時，多樣派發（multiple-dispatch）將會依型別確定要應用的有效方法。如下列範例展示了對不同型別的參數如數值、向量或字串，設計對應的codice_26方法將兩個物件相加的動作。
泛化函數也是第一類数据类别。除了上面陳述之外，泛化函數和方法還有更多的特性。
函数的名字空间与数据变量的名字空间是分离的。这是Common Lisp和Scheme编程语言的一个重要不同之处。在函数名字空间定义名字的操作符包括codice_21,codice_28，和codice_29。
要用函数名把函数作为参数传给另一个函数，必须使用codice_30特殊操作符，通常简略为#'。上文第一个codice_15的例子中，为了引用在函数名字空间名为codice_32的函数，使用了代码codice_33。
Scheme编程语言的求值模型更简单些：因为只有一个名字空间，式（form）中所有位置都被求值（以任意顺序）-- 不仅是参数。所以以一种方言（dialect）写就的代码往往令熟悉其它方言程序员感到迷惑。例如，许多CL程序员喜欢使用描述性的变量名如"list"或"string"，在Scheme中这将导致问题，因为它们可能局部覆盖了函数名字。
为函数提供分离的名字空间是否有益是Lisp社区不断争论的主题之一，常被称为“Lisp-1与Lisp-2辩论”。这些名称出现于和在1998年的一篇论文，其中广泛的比较了这两种方法。
Common Lisp支援多值的概念，任何表達式經過評估之後必定會有一個主要值，但它也可能擁有任何數量的次要值，讓感興趣的呼叫者接收和檢查。這個概念與回傳列表值不同，因為次要值是備選用的，並通過專用的側面通道來傳遞。也就是說如果不需要次要值，則呼叫者完全不需要知道它們的存在，這是偶爾需使用額外而非必要的資訊，一個方便的機制。
一些標準形式支援多值，最常見的是用來存取次要值的codice_36基本運算子和用於返回多值的codice_37：
Common Lisp中的其他数据类别包括：
與許多其它編程語言中的程式一樣，Common Lisp編程使用名稱來引用變量、函數和許多其它類型的實體。被命名的參照只在其作用域中有用。名稱與引用實體之間的關聯稱為綁定。作用域是指確定名稱具有特殊綁定的情況。
在Common Lisp中需要決定作用域的情況包括：要理解符號參照到什麼實體，Common Lisp開發人員必須知道參照是屬於哪一種作用域，如果它是一個變量的參照，那它是處於什麼樣的（動態或詞法的）作用域中？以及在執行期的情況，參照在什麼環境中被引用，綁定是在哪裡被引入到環境等等。
Lisp中的一些環境總是存在於全局作用域之中， 例如定義了一個新型別，那麼以後在任何地方都會知道它。 該類型別的參照會從全局作用域中的環境去尋找。
環境在Common Lisp中有一種類型是動態環境。在這種環境中建立的綁定具有動態的作用域，這表示某些構造例如codice_56，會在執行的起點就先建立綁定，而在該構造完成執行時消失：它的生命週期依附著這區塊動態地觸發和停用。然而動態綁定不僅在該區塊中可見；對於從該區塊中調用的所有函數也是可見的。這樣的可見性被稱為不定的作用域。具有動態（依附區塊的觸發和停用相關的生命週期）和不定作用域（從該區塊調用的所有函數可見）的綁定，被稱為具有動態作用域。
Common Lisp支援動態作用域的變量，也稱為特殊變量。有些其它類型的綁定也必須是動態作用域的，例如重新啟動和捕獲標籤。函數綁定不能以codice_28（僅提供詞法範圍的函數綁定）進行動態作用域，但可以將函數物件（Common Lisp中的第一類物件）分配給動態作用域的變量，在動態作用域內使用codice_56綁定，然後再以codice_62或codice_63調用。
動態作用域非常有用，因為它將參照的清晰度和規律添加到全局變量中。計算機科學中的全局變量被認為是潛在的錯誤來源，因為它們可能導致模組之間存有特殊隱蔽的溝通渠道，從而導致令人驚訝而不在預期中的交互作用。
在Common Lisp中，只有頂層綁定的特殊變量就像其它編程語言中的全局變量一樣。它可以儲存一個新的值，該值僅替換頂層綁定中的值。造成使用全局變量的核心錯誤，是粗心的替代了全局變量值。但是，使用特殊變量的另一種方法是，在表達式中給它一個新的區域綁定。這有時被稱為“重新綁定”變量。動態作用域中對變量的綁定，會創建一個臨時的新記憶體位置給予該變量，並將該名稱與該位置相關聯。當該綁定有效，對該變量的所有參照都指向新的綁定；之前的綁定則是被隱藏起來的。當綁定表達式的執行結束時，臨時的記憶體位置消失，而舊綁定浮現出來，變量的原始值依舊完好無損。當然，同一變量的多個動態綁定可以嵌套。
在支援多緒的Common Lisp實作中，動態作用域是針對每個執行緒的。因此，特殊變量是當成執行緒區域存儲的抽象化。如果一個執行緒重新綁定了特殊變量，則此重新綁定對其它執行緒中的該變量沒有作用。儲存在綁定中的值只能由創建該綁定的執行緒取得。如果每個執行緒綁定一些特殊變量codice_64，則codice_64的行為就像執行緒在本地中儲存一樣。在沒有重新綁定codice_64的執行緒中，它的行為就像一個普通的全局變量：所有這些執行緒的參照都會指向codice_64的頂層綁定。
動態變量可以用來擴展執行上下文，並附加上下文訊息，這些信息在函數之間隱含地傳遞，而不必顯示為額外的函數參數。當執行控制的轉移必須穿過不相關的代碼層時，不能藉由額外參數來擴展傳遞附加數據，所以這是非常有用的。這樣的情況通常需要一個全局變量，必須能夠被儲存和恢復，以便在遞歸時不會中斷：動態變量的重新綁定可以處理此情形。該變量必須是執行緒區域的（或必須使用大的互斥, mutex），因此這個情況不會在執行緒下斷開：動態作用域的實作也可以處理此情形。
在Common Lisp函式庫中有很多標準的特殊變量。例如，所有標準I/O流都儲存在頂層為眾所熟知的特殊變量的綁定中，即codice_68。
假設有個foo函數寫入標準輸出： 要擷取其輸出中的字串，codice_68可以被綁定到一個字串流，並調用它：
Common Lisp支援詞法環境。形式上，詞法環境中的綁定具有詞法作用域，並可能具有不定的範圍或動態的範圍，取決於命名空間的類型。詞法作用域實際上表示可見性被限制在綁定建立的區塊中。參照沒有以文本（即詞法地）嵌入在該區塊中，根本看不到該綁定。
codice_70中的標籤會具有詞法作用域。如果(GO X)表達式實際上沒有嵌入到其中，則它會發生錯誤。codice_70包含標籤codice_72。但是當codice_70執行終了時，標籤的綁定就會消失，因為它們具有動態作用域。如果以調用一個詞法閉包重新進入該代碼區塊，那麼這個閉包的內文無法藉由codice_74將控制轉移到標籤中：
執行codice_70時，它首先評估以codice_76形式指向函數的特殊變量codice_77，然後codice_78將控件轉移到終了標籤，跳過代碼codice_79。由於終了標籤位於codice_70的末端，於是終止並返回codice_13值。假設現在調用先前指向的函數： 這種狀況是錯誤的。一個實作的錯誤回應該包含錯誤條件訊息，例如“GO: tagbody for tag SOME-LABEL has already been left”。該函數嘗試評估codice_82，它是詞法地嵌入到codice_70中並解析為標籤。然而codice_70被跳過了而沒有執行（其作用域已經結束），故無法再轉移控制。
Lisp中的區域函數綁定具有詞法作用域，預設情況下變量綁定也同樣為詞法作用域。與codice_74標籤對比，它們的作用域是範圍不定的。當一個詞法的函數或變量綁定時，既然可以對其引用參照，該綁定就會持續存在，即使在建立該綁定的結構已經終止後。參照到詞法變量和函數，在其建立結構終止後，可以藉由詞法的閉包來實現。
Common Lisp對於變量的預設模式是詞法綁定。對於個別符號可用區域聲明，或全局的聲明，來切換成動態作用域。而後者可能隱含地透過如codice_86或codice_87，這樣的構造使符號成為全局可見的。Common Lisp編程中慣例以開頭和結尾星號codice_88，將特殊變量（即處於動態作用域的）包括起來，這稱為“耳罩慣例”。遵循此慣例的效果，即為特殊變量創建了一個單獨的命名空間，則應該處於詞法作用域的變量不會被意外地特殊化。
幾個原因使得詞法作用域有用。
首先，變量和函數的參照可以被編譯成高效的機器碼，因為執行期環境的結構相對簡單。在許多情況下它可以優化堆疊存儲，因此開啟和關閉的詞法作用域前置開銷最小。即使在必定要產生完整閉包的情況下，存取閉包的環境仍然是有效率的；每個變量通常會轉成一個綁定向量之中的偏移量，因此變量的參照就成為簡單的加載，或是以基底-加-偏移尋址模式表示的存儲指令。
其次詞法作用域（與不定範圍結合）可以創造出詞彙閉包，從而產生了中心以函數作為第一類物件的編程範式，這是函數式編程的根本。
第三，也許最重要的是，即使沒有用到詞法的閉包，詞法作用域的運用，會將程序模組與不需要的交互影響隔離開來。由於可見性受到限制，詞法變量是私有的。如果一個模組A綁定一個詞法變量X，並呼叫另一個模組B，則參照B其中的變量X，不會被意外地解析成在A中綁定的X。B根本無法存取X。對於需使用變量進行有規則的交互作用情況，Common Lisp提供了特殊變量。特殊變量允許一個模組A設置變量X的綁定，使另一模組B能看見並從A調用其中的X。能夠做到這一點是個優勢，能夠防止它發生也是個優勢；因此Common Lisp同時支援詞法和動態作用域兩者。
Common Lisp中的巨集是独一无二的，和C语言中的巨集的机制相同，但是在巨集扩展的过程中由于可以使用所有现有的Common Lisp功能，因此巨集的功能就不再仅限于C语言中简单的文本替换，而是更高级的代码生成功能。巨集的使用形式和函数一致，但是巨集的参数在传递时不进行求值，而是以"字面形式"传递给巨集的参数。巨集的参数一旦传递完毕，就进行"展开"。展开巨集的过程将一直进行到这段代码中的所有巨集都展开完毕为止。巨集完全展开完毕后，就和当初直接手写在此处的代码没有区别，也就是嵌入了这段代码上下文中，然后Lisp系统就对完整的代码上下文进行求值。
Lisp巨集表面上類似於函數的使用，但並不是會直接被求值的表達式，它代表程序源碼的字面轉換。巨集將包含的代碼內容當作參數，將它們綁定到巨集自身的參數，並轉換為新的源碼形式。這個新的源碼形式也能夠使用一個巨集，然後重複擴展，直到新的源碼形式沒有再用到巨集。最終形式即運行時所執行的源代碼。
Lisp巨集的典型用途：
各種標準的Common Lisp功能也需要巨集來實現，如以下所列： 巨集是以codice_96來定義。基本運算子codice_97允許定義區域性的（詞法作用域）巨集。也可以使用codice_98和codice_99，為符號定義巨集。Paul Graham的《On Lisp》書籍詳細介紹了Common Lisp中巨集的用途。Doug Hoyte的《Let Over Lambda》書籍擴展了關於巨集的討論，聲稱「巨集是lisp編程最獨特的優勢，和任何編程語言的最大優點」。Hoyte提供了迭代開發的幾個巨集範例。 Lisp編程人員能夠利用巨集來創造新的語法形式。典型的用途是創建新的控制結構。 此處提供一個codice_100循環結構的巨集範例，其語法如下： codice_100巨集的定義： codice_44是一個基本的Common Lisp運算子，它提供了命名標籤的能力，並使用codice_103形式跳轉到這些標籤。 反引號codice_104的用途類似單引號codice_105（相當於quote函數，引用形式當成資料而不求值），它還是一個可作代碼模板 的符號，其中需要求值的形式參數以逗號codice_106開頭填入模板；而以codice_107符號為開頭的形式參數，其中嵌套的內容會 再被拆解評估。codice_44形式測試結束條件。如果條件為真，則跳轉到結束標籤；否則執行主體的代碼， 然後跳轉到起始標記。
上述codice_100巨集的使用範例： 利用codice_110函數可以展開巨集的代碼。上例經過展開後的代碼如下所示： (TAGBODY 在巨集展開期間，變量codice_111的值為codice_112，變量codice_113的值為codice_114，是一個列表形式。
符號通常會自動轉成英文大寫。這個codice_70擴展中帶有兩個標籤符號，由codice_116自動產生，並且不會被拘束到任何套件中（為待綁定的暫時自由變量）。兩個codice_103形式會跳轉到這些標籤，因為codice_44是Common Lisp中的基本運算子（並不是巨集），因此它沒有其它內容會再展開。展開形式中用到的codice_93巨集也會再展開。將一個巨集完全展開為源代碼的形式，被稱為代碼走開（code walking）。在已被完全展開的形式中，codice_93巨集會被基本運算子codice_92代換： (TAGBODY 源碼中所有包含的巨集必須在展開之後，才能正常地評估或編譯。巨集可以理解為接受和返回抽象語法樹（Lisp S-表達式）的函數。 這些函數會在求值器或編譯器調用之前，將巨集內容轉換為完整的源碼，Common Lisp中所提供的任何運算子都可用於編寫巨集。
因为Common Lisp的巨集在展开完毕后就完全嵌入了所处的代码上下文中，相当于以字面形式书写同样的代码，因此在巨集展开代码中与上下文代码中相同的符号就会覆盖上面的引用，称为"变量捕捉"。如果Common Lisp的巨集展開代碼中的符號，與調用上下文中的符號相同時，通常稱為變量捕捉。對於巨集，程序員可在其中創建具有特殊含義的各種符號。變量捕捉這個術語可能有點誤導，因為所有的命名空間都有非預期捕捉到相同符號的弱點，包括運算子和函數的命名空間、codice_44標籤的命名空間、codice_123標記，條件處理程序和重新啟動的命名空間。
變量捕捉情況會使軟件產生缺陷，發生原因可分為下列兩種方式：Lisp語族的Scheme方言提供了一個巨集寫入系統，它提供了參照透明度來消除這兩種類型的捕捉問題。這樣的巨集寫入系統有時被稱為“保健的”，特別是其支持者（認為不能自動解決捕捉問題的巨集系統是不正確的）。
在Common Lisp中巨集的保健，則以兩種不同方式擔保。
一種方法是使用codice_124：保證只產生唯一的符號在巨集擴展中使用，而不受到捕捉問題的威脅。在巨集定義中使用codice_124是件零瑣的雜務，但利用巨集可簡便codice_124的實例化和使用。codice_124很容易解決類型二的捕捉問題，但它們不能以相同方式來處理類型一的捕捉問題，因為巨集展開不能重新命名，周圍代碼中參照所捕捉到的介入符號（被區域定義遮蔽的全局符號）。codice_128可以為巨集擴展所需要的全局符號，提供穩定的別名。巨集擴展使用這些秘密別名而非眾所熟知的名稱，因此重新定義熟知的名稱對巨集並沒有不利影響。
另一種方法是使用套件，在自己套件中定義的巨集，在套件中的擴展可以簡單地使用內部符號。使用套件能處理類型一和類型二捕捉問題。然而，套件不能解決參照到Common Lisp標準函數和運算子的類型一捕捉，因為用套件來解決捕捉問題，只能解析其私有符號（套件中的符號不是導入的，或能被其它套件看見的）；而Common Lisp函式庫的符號都是外部共用的，並經常導入到使用者定義套件中，或在使用者定義套件中是可見的。
以下範例是在巨集展開時，運算子命名空間中發生的不預期捕捉：
codice_100巨集將展開為一個調用codice_130功能的形式，該形式旨在引用Common Lisp標準的codice_130巨集。但在這種情況下，codice_130可能有完全不同的含義，所以codice_100可能無法正常工作。
Common Lisp禁止對標準運算子和函數的重新定義，避免它們的遮蔽來解決此類問題。因為前例重新定義了codice_130標準運算子，實際上是一個不合格的代碼片段，Common Lisp實作應當對前例進行診斷並拒絕其重新定義。
條件系統負責Common Lisp中的異常處理。它提供條件，處理程序和重新啟動。條件是描述異常情況（例如錯誤）的物件。如果一個條件訊號被發出了，Common Lisp系統將搜索此條件類型的處理程序並調用它。處理程序現在可以搜索重新啟動（restart），並使用這些重新啟動之一來自動修復當前的問題，利用條件類型與條件物件的一部份所提供的任何相關資訊等，並調用相對的重新啟動函數。
如果沒有處理程序的代碼，這些重新啟動可以對使用者顯示選項（作為使用者介面的一部分，例如除錯器），讓使用者選擇和調用提供的重新啟動選項。由於條件處理程序在錯誤的上下文中被調用（堆疊仍未清空），在許多情況下對錯誤的完全回復處理是可行的，而不同於其它的異常處理系統可能已經終止了當前的執行程序。除錯器本身也可以使用codice_135這個動態變量來客製或替換。在codice_136中寫明的代碼，譬如作為終結，也會適當地被執行例外。
以下範例（使用 Symbolics Genera）中，使用者從讀取求值打印循環（REPL，即頂層）呼叫一個test函數，嘗試開啟一個檔案，而當此檔案不存在時，Lisp系統則呈現四個重新啟動的選項。使用者選擇了codice_137這個重新啟動選項，並輸入不同的路徑名稱（以lispm-init.lisp取代了lispm-int.lisp）。使用者執行的源碼中並沒有包含任何錯誤處理。整個錯誤處理和重新啟動代碼是由Lisp系統本身所提供，它可以處理和修復錯誤，而不終止使用者執行中的程序碼。 Command: (test ">zippy>lispm-int.lisp")
Error: The file was not found.
LMFS:OPEN-LOCAL-LMFS-1
s-A, : Retry OPEN of lispm:>zippy>lispm-int.lisp.newest s-B: Retry OPEN using a different pathname s-C, : Return to Lisp Top Level in a TELNET server s-D: Restart process TELNET terminal
-> Retry OPEN using a different pathname Use what pathname instead [default lispm:>zippy>lispm-int.lisp.newest]:
...the program continues Common Lisp包含了物件導向編程的工具包，Common Lisp物件系統或簡稱為CLOS，它是最強大的物件系統之一。Peter Norvig 解釋了在具備CLOS的動態語言中，如何使用其功能（多重繼承，混合，多方法，元類，方法組合等），以達成設計模式更簡單的實現。曾經有幾個擴展被提出來作為Common Lisp ANSI標準的物件導向編程應用，而最終採用了CLOS作為Common Lisp的標準物件系統。
CLOS是個具有多分派和多重繼承的動態物件系統，並且與靜態語言（如C++ 或Java）中的OOP設施截然不同。作為動態物件系統，CLOS允許在執行時期對泛化函數和類別進行更改。方法可以添加和刪除，類別可以添加和重新定義，物件可依照類別的變動更新，而物件所屬的類別也可以更改。CLOS已經整合到ANSI Common Lisp中。通过函數可以像普通函數一樣使用，並且是第一類資料類型。每個CLOS類別都已被整合到Common Lisp類別系統中。
Common Lisp中許多型別都有一個相對應的類別。規範中沒有說明CLOS實作的條件，CLOS進階用法的可能性並不是Common Lisp的ANSI標準，CLOS的用處有更多的潛能。一般Common Lisp實作將CLOS用於路徑名稱、流、輸入/輸出、條件，CLOS本身等等。
早期Lisp方言的幾個實現提供了直譯器和編譯器，不幸的是兩者之間語義是不同的。這些早期的Lisps在編譯器中實作了詞法作用域，在直譯器中實作了動態作用域。Common Lisp要求直譯器和編譯器兩者皆預設使用詞法作用域。Common Lisp標準描述了直譯器和編譯器的語義。可以使用codice_23 函數呼叫編譯器，來編譯各個函數，並使用codice_139函數編譯源碼檔案。Common Lisp允許類型別聲明，並提供產生編譯器代碼的選擇。後者有優化參數可選擇0（不重要）和3（最重要）之間的值：會影響到"執行速度"，"空間"，"安全性"，"除錯"和"編譯速度"。
還有一個函數用來評估Lisp源碼：codice_140。codice_140將源碼視為預先解析的S-表達式，而不像其它語言只當成字串處理。這樣可以用常見的Lisp函數來建構代碼，用來構造列表和符號，然後以codice_140函數來評估該代碼。幾個Common Lisp實作（如Clozure CL和SBCL）以它們的編譯器來實現codice_140。這樣子即使用codice_140函數進行評估時，源碼也是會被編譯。
使用codice_139函數呼叫檔案編譯器，產生的編譯檔稱為fasl（快速加載，fast load）檔案。這些fasl檔案和源碼檔案都能以codice_146功能，加載到運行的Common Lisp系統中。根據實作，檔案編譯器會產生位元組碼（例如Java虛擬機），C語言代碼（然後以C編譯器編譯）或直接使用原生機器碼。
即使源碼已經完全被編譯，Common Lisp實作可以和使用者互動。因此，Common Lisp的互動介面並非類比於直譯腳本的設想。
這個語言區隔了讀取時期、編譯時期、加載時期和執行時期，並讓使用者編程在需求的步驟中，也依照這些區別來執行所需的處理種類。
有些特殊的運算子特別適合互動式開發；譬如，若codice_147還沒有任何綁定時，則只對提供給它的變量進行賦值；而codice_148總是會執行賦值。在實時映像中互動地評估，編譯和載入代碼時，這種區別是有用的。還有一些功能也幫助撰寫編譯器和直譯器。符號由第一類物件所組成，可由使用者的代碼直接操縱。codice_149基本運算子允許以編程方式創造詞法綁定，也可以運用套件。Lisp編譯器本身在運行時可用來編譯檔案或單一函數，這使得Lisp成為其它編程語言的中途編譯器或直譯器變得容易。
以下程序計算一個房間內最小數量的人，其完全獨特生日的概率小於 50％（生日悖論，1 人的概率明顯為 100％，2 為 364/365 等）。答案是 23。
(defconstant +year-size+ 365)
使用REPL呼叫函數用例：
CL-USER > (birthday-paradox 1.0 1) 23 我們定義一個人員類別和一個顯示姓名和年齡的方法。接下來，我們將一組人定義為人物物件列表。然後我們遍歷排序列表。
(defparameter *group*
它以降序打印三個名字。
Bob (33) Ash (23) Chris (16) 使用LOOP宏：
使用示例：
CL-USER > (power 2 200) 1606938044258990275541962092341162602522202993782792835301376 與內建的求冪函數比較：
CL-USER > (= (expt 2 200) (power 2 200)) T codice_150是打开一个文件并提供一个串流的宏。在这个形式返回的时候，这个文件自动关闭。codice_151调用一个函数对象。codice_2收集匹配谓词的所有行： 函数codice_153调用上述codice_154函数，并以一个路径名和作为谓词的一个匿名函数作为参数。这个谓词返回一个shell的路径名或codice_13（如果这个字符串不是一个shell的路径名）： 例子结果（在Mac OS X 10.6之上）： CL-USER > (available-shells) Common Lisp經常和Scheme互相比較，因為它們是最受歡迎的兩種Lisp方言。Scheme早於CL，不僅來自同一個Lisp傳統，而且是Guy L. Steele與Gerald Jay Sussman設計的，Guy L. Steele也擔任過Common Lisp標準委員會的主席。
Common Lisp是一種普遍用途的的編程語言；相反的如Emacs Lisp和AutoLISP這兩種Lisp的變體，則是嵌入特定產品作為擴展用的語言。與許多早期的Lisps不同，Common Lisp（Scheme同樣）對源碼直譯和編譯時，預設為詞法變量作用域。
大部份Lisp系統（如ZetaLisp和Franz Lisp）的設計，促成了Common Lisp在直譯器中使用動態作用域的變量，並在編譯器中使用了詞法作用域的變量。由於ALGOL 68的啟發，Scheme引入了Lisp對詞法作用域變量的單一使用；這被廣泛認同是好主意。CL也支援動態作用域的變量，但必須將其顯式聲明為“特殊”。ANSI CL直譯器和編譯器之間的作用域界定是沒有差別的。
Common Lisp有時被稱為Lisp-2，而Scheme被稱為Lisp-1。它指的是CL對函數和變量使用個別的命名空間（實際上CL有許多命名空間，例如codice_103標籤，codice_157名稱和codice_95關鍵字）。在涉及多個命名空間的權衡之間，CL與Scheme倡導者之間存在著長期的爭議。在Scheme中（廣義地）必須避免與函數名稱互相衝突的變量名稱；Scheme函數通常擁有名稱為codice_159，codice_160或codice_161的參數，以免與系統內建的codice_162函數衝突。然而在CL中，在傳遞函數作為參數時一定要顯式地引用函數的名稱空間，這也是一個常見的事件，如前面小節中的排序編程範例。
在處理布爾邏輯值時，CL也與Scheme不同。Scheme使用特殊值#t和#f來表示邏輯真與假值。而CL遵循使用符號T和NIL的傳統Lisp慣例，NIL同時也是空列表。在CL中任何非NIL值被條件處理為真，例如codice_92；而在Scheme當中，所有非#f值被視為真。這些慣例約定允許這兩種語言的一些運算子同時作為謂詞（回應邏輯上的是非問題），並返回一個作用值進行進一步的計算，但在Scheme的布爾表達式中，等同於Common Lisp空列表的NIL值或'()，會被評估為真。
最後，Scheme的標準文件要求尾部呼叫優化，而CL標準沒有。不過大多數CL實作會提供尾部呼叫優化，雖然通常只在程序員使用優化指令時。儘管如此，常見的CL編程風格並不偏好於Scheme中普遍使用的遞歸樣式- 一個Scheme程序員會使用尾部遞歸表達式，CL使用者則通常會用codice_130，codice_165，codice_95等迭代表達式，或使用codice_167套件來表達。
Common Lisp是由一份技术规范定义而不是被某一种具体实现定义（前者的例子有Ada语言和C语言，后者有Perl语言）。存在很多种实现，语言标准详细阐明了可能导致合理歧义的内容。
另外，各种实现试图引入套件或函式库来提供标准没有提及的功能，可能的擴充功能如下所列：
可移植的自由软件库提供了各种特性，著名的有Common-Lisp.net和Common Lisp Open Code Collection项目。
Common Lisp设计为由增量编译器实现。优化编译的标准声明（例如内联函数）已进入语言规范的计划。大多数Lisp实现将函数编译成原生的机器语言。其他的编译器编译为中间码，有损速度但是容易实现二进制代码的可移植。由于Lisp提供了交互式的提示符以及函数增量式的依次编译，很多人误会为Lisp是纯解释语言。
一些基于Unix的实现，例如CLISP，可以作为脚本解释器使用；因此，系统可以像调用Perl或者Unix shell解释器一样透明地调用它。 免费的可重发布实现包括：
商业实现在Franz, Inc.，Xanalys Corp.，Digitool, Inc.，Corman Technologies和Scieneer Pty Ltd.。
Common Lisp被用于很多成功的商业应用中，最著名的（毫无疑问要归功于Paul Graham的推广）要数Yahoo!商店的站点。其他值得一提的例子有：也有很多成功的开源应用用Common Lisp写成，例如：同样，Common Lisp也被许多政府和非盈利组织采用。NASA中的例子有：