Common Lisp

Common Lisp，縮寫為CL，所定義的語言規範標準。Common Lisp HyperSpec是源自於ANSI Common Lisp標準的網頁超連結版本。CL語言是為標準化和改良Maclisp而開發的後繼者。到20世紀80年代初，幾個工作群組已經在設計MacLisp各種後繼者，例如：Lisp Machine Lisp，Spice Lisp，NIL和S-1 Lisp。CL是為了標準化和擴充套件此前眾多的MacLisp分支而開發，它本身並非具體的實作，而是對語言設立標準的規範。有數個實作符合Common Lisp規範，其中包括自由和開源軟體，以及商業化產品。CL支援了結構化、函式式和物件導向程式設計等正規化。相對於各種嵌入在特定產品中的語言，如Emacs Lisp和AutoLISP，Common Lisp是一種用途廣泛的程式語言。不同於很多早期Lisp，Common Lisp如同Scheme，其中的變數是預設為詞法作用域的。身為一種動態程式語言，它有助於進化和增量的軟體開發，並將其迭代編譯成高效的執行程式。這種增量開發通常是互動持續地改善，而不需中斷執行中的應用程式。它還支援在後期的分析和最佳化階段新增可選的型別註記與轉型，使編譯器產生更有效率的程式碼。例如在硬體和實作的支援範圍內，codice_1能儲存一個未封裝整數，允許比大整數或任意精度型別更高效率的運算。同樣地，在每個模組或函式的基礎上可宣告最佳化，指示編譯器要編譯成哪一型別的安全級別。CL包含了支援多分派和方法組合的物件系統，縮寫為CLOS，它通常以元物件協定來實現。CL藉由標準功能進行擴充套件，例如Lisp宏。CL為Maclisp和約翰·麥卡錫的原創Lisp提供了一些向後相容性。這允許較舊的Lisp軟體移植到Common Lisp之上。歷史.在1981年，ARPA管理者Bob Engelmore最初發起了關於Common Lisp的工作，開發一個單一的社群標準Lisp方言。大多數最初的語言設計是透過電子郵件完成的。在1982年，Guy L. Steele Jr.於1982年度LISP和函數語言程式設計研討會上首次給出了Common Lisp的概述。在1984年，首個語言文件被出版為《》，第一版都由實現和函式庫來提供。語法.Common Lisp是Lisp程式設計語族的一種方言; 它使用S-表示式來表示原始碼和資料結構。函式呼叫、宏形式和基本形式都以列表來編寫，列表的第一項是函式名稱，如以下範例：(+ 2 2) ; 將 2 加上2 得 4。函式名稱為'+'，在Lisp語法中是唯一的(只能作用於數值)。(defvar *x*) ; 先確保 *x* 變數存在，尚未賦值給它。星號也是變數名稱的一部份，; 依慣例約定表示一個特殊變數。符號 *x* 與生俱有的屬性是; 對於它後續的繫結是動態可變的，而非詞法靜止不變的。(setf *x* 42.1) ; 對 *x* 變數賦予浮點數值 42.1。;; 定義計算一個數的平方函式：(defun square (x)(* x x));; 執行這個函式：(square 3) ; 返回平方值 9;; 'let'構造為區域變數建立一個作用域。這裡變數'a' 被繫結到 6，變數'b'被繫結到 4。;; 'let'的內部是一個函式體，對它求值後會返回最後一個計算值。這個'let'表示式將;; a 和 b 相加的結果返回。變數 a 和 b 只存在於詞法作用域中，除非它們已先被標記;; 成特殊變數。(let ((a 6)(b 4))(+ a b)) ; 返回數值 10資料類別.Common Lisp 擁有豐富的資料類別。純量型別.數值型別包括整數，分數，浮點數和複數。Common Lisp使用大數來表示任意大小和精度的數值。分數型別確切地代表分數，很多語言並不具備這種能力。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字元。符號。資料結構.Common Lisp的序列型別包括列表、向量、位元向量和字串。有許多函式可對應不同型別的序列進行操作。CL如同所有Lisp方言，列表由點對。而除了最後一個的CDR參照到codice_14值之外，其餘的CDR都會參照下一個點對。Conses也能輕易地實現樹和其它複雜的資料結構；儘管一般建議以結構體或是類別的例項來代替。利用點對能夠建立迴圈形的資料結構。CL支援多維陣列，且如需要能動態地調整陣列大小。多維陣列常用於數學中的矩陣運算。向量就是一維陣列。陣列可載入任何型別的成員，或只專用於特定某一型別的成員，例如由整數構成的位元向量。許多Lisp實作會根據特定型別，對陣列的操作函式進行最佳化。兩種特定型別的專用陣列是內建的：字串和位元向量。字串是由許多字元構成的向量，而位元向量是由許多位元構成的向量。散列表儲存物件之間的關聯，任何物件都可以作為散列表的鍵或值。和陣列一樣，散列表可依需求自動調整其大小。套件是一組符號的集合，主要用於將程式的個別部份區分名稱空間。套件能匯出一些符號，將它們作為共用介面的某一部份，也可以匯入其它套件引用並概括承受其中的符號。CL的結構體。結構允許單一繼承。類別的雙重角色，泛型既是函式，也是類別的例項物件。函式.Common Lisp支援頭等函式。例如編寫以其它函式當作一個函式的引數，或函式的傳回值也是函式，利用函式的結合來描述常用的操作。CL函式庫高度依賴於這樣的高階函式變換。舉例而言，codice_15函式可將關係運運算元作為引數，並選用如何取鍵的函式作為引數。如此一來不但能對任何型別的資料排序，還能根據取用的鍵值對資料結構作排序。;; 使用大小於函式作為比較關係，對列表進行排序。(sort (list 5 2 6 3 1 4) #'&gt;) ; 大於比較排序結果 (6 5 4 3 2 1)(sort (list 5 2 6 3 1 4) #' (available-shells)Common Lisp與Scheme的比較.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對原始碼直譯和編譯時，預設為詞法變數作用域。大部份Lisp系統的設計，促成了Common Lisp在直譯器中使用動態作用域的變數，並在編譯器中使用了詞法作用域的變數。由於ALGOL 68的啟發，Scheme引入了Lisp對詞法作用域變數的單一使用；這被廣泛認同是好主意。CL也支援動態作用域的變數，但必須將其顯式宣告為“特殊”。ANSI CL直譯器和編譯器之間的作用域界定是沒有差別的。Common Lisp有時被稱為Lisp-2，而Scheme被稱為Lisp-1。它指的是CL對函式和變數使用個別的名稱空間必須避免與函式名稱互相衝突的變數名稱；Scheme函式通常擁有名稱為codice_161，codice_162或codice_163的引數，以免與系統內建的codice_164函式衝突。然而在CL中，在傳遞函式作為引數時一定要顯式地引用函式的名稱空間，這也是一個常見的事件，如前面小節中的排序程式設計範例。在處理布林邏輯值時，CL也與Scheme不同。Scheme使用特殊值#t和#f來表示邏輯真與假值。而CL遵循使用符號T和NIL的傳統Lisp慣例，NIL同時也是空列表。在CL中任何非NIL值被條件處理為真，例如codice_94；而在Scheme當中，所有非#f值被視為真。這些慣例約定允許這兩種語言的一些運運算元同時作為謂詞，並返回一個作用值進行進一步的計算，但在Scheme的布林表示式中，等同於Common Lisp空列表的NIL值或'()，會被評估為真。最後，Scheme的標準檔案要求尾部呼叫最佳化，而CL標準沒有。不過大多數CL實作會提供尾部呼叫最佳化，雖然通常只在程式設計師使用最佳化指令時。儘管如此，常見的CL程式設計風格並不偏好於Scheme中普遍使用的遞迴樣式- 一個Scheme程式設計師會使用尾部遞迴表示式，CL使用者則通常會用codice_132，codice_167，codice_97等迭代表達式，或使用codice_169套件來表達。實現.Common Lisp是由一份技術規範定義而不是被某一種具體實現定義。存在很多種實現，語言標準詳細闡明瞭可能導致合理歧義的內容。另外，各種實現試圖引入套件或函式庫來提供標準沒有提及的功能，可能的擴充功能如下所列：可移植的自由軟體庫提供了各種特性，著名的有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被用於很多成功的商業應用中，最著名的要數Yahoo!商店的站點。其他值得一提的例子有：也有很多成功的開源應用用Common Lisp寫成，例如：同樣，Common Lisp也被許多政府和非盈利組織採用。NASA中的例子有：