Lisp是一個計算機程式語言,具有悠久的歷史和獨特的,帶有完全括弧的前綴表示法。Lisp最初是在1958年指定的,是廣泛使用的第二古老的高級程式語言。 只有Fortran年齡大一歲。Lisp從早期開始就發生了變化,許多方言都存在於其歷史之中。最著名的通用Lisp方言是Common Lisp和Scheme。
基本介紹
- 外文名:Lisp
- 本質:計算機程式語言
介紹,Common Lisp,語言創新,例子,
介紹
Lisp最初是作為電腦程式的實用數學符號而創建的,受Alonzo Church的lambda演算符號的影響。它很快成為人工智慧(AI)研究的首選程式語言。作為最早的程式語言之一,Lisp在計算機科學領域開創了許多思想,包括樹數據結構,自動存儲管理,動態類型,條件,高階函式,遞歸,自託管編譯器,和閱讀eval-print循環。
LISP這個名字源自“LISt處理器”。[8]鍊表是Lisp的主要數據結構之一,Lisp原始碼由列表組成。因此,Lisp程式可以將原始碼作為數據結構進行操作,從而產生允許程式設計師創建新語法或嵌入在Lisp中的新域特定語言的宏系統。
代碼和數據的可互換性為Lisp提供了可立即識別的語法。所有程式代碼都寫為s表達式或帶括弧的列表。函式調用或語法形式首先寫成一個帶有函式或運算符名稱的列表,然後是參數;例如,一個帶三個參數的函式f將被稱為(f arg1 arg2 arg3)。
Common Lisp
Common Lisp和Scheme代表了Lisp開發的兩個主要流程。這些語言體現了截然不同的設計選擇。
Common Lisp是Maclisp的繼承者。主要影響是Lisp Machine Lisp,Maclisp,NIL,S-1 Lisp,Spice Lisp和Scheme。它具有Lisp Machine Lisp(用於編程Lisp機器的大型Lisp方言)的許多功能,但其設計可在任何個人計算機或工作站上高效實現。 Common Lisp是一種通用程式語言,因此具有大型語言標準,包括許多內置數據類型,函式,宏和其他語言元素,以及對象系統(Common Lisp Object System)。 Common Lisp還借用了Scheme中的某些功能,例如詞法範圍和詞法閉包。 Common Lisp實現可用於針對不同的平台,例如LLVM,Java虛擬機,x86-64,PowerPC,Alpha,ARM,Motorola 68000和MIPS。以及Windows等作業系統,Mac OS X,Linux,Solaris,FreeBSD,NetBSD,OpenBSD,Dragonfly BSD和Heroku。
Scheme是由Guy L. Steele,Jr。和Gerald Jay Sussman發明的Lisp程式語言的靜態範圍和正確的尾遞歸方言。它被設計為具有異常清晰和簡單的語義,並且幾乎沒有形成表達式的不同方式。 Scheme比Common Lisp早了大約十年,它是一個更簡約的設計。它具有更小的標準功能集,但具有Common Lisp中未指定的某些實現功能(如尾調用最佳化和完全延續)。各種編程範例,包括命令式,功能性和訊息傳遞樣式,在Scheme中找到方便的表達式。 Scheme繼續發展,採用一系列標準(Revisedn Report of the Algorithmic Language Scheme)和一系列實施方案請求。
Clojure是Lisp的最新方言,主要針對Java虛擬機,以及公共語言運行時(CLR),Python VM,Ruby VM YARV以及編譯為JavaScript。它旨在成為一種實用的通用語言。 Clojure吸引了Haskell的相當大的影響,並非常強調不變性。[40] Clojure提供對Java框架和庫的訪問,具有可選的類型提示和類型推斷,因此對Java的調用可以避免反射並啟用快速原始操作。
此外,Lisp方言在許多應用程式中用作腳本語言,最著名的是Emacs編輯器中的Emacs Lisp,AutoCAD中的AutoLISP和後來的Visual Lisp,Audacity中的Nyquist,LilyPond中的Scheme。有用的Scheme解釋器的潛在小尺寸使其特別適用於嵌入式腳本。示例包括SIOD和TinyScheme,兩者都已成功嵌入GIMP圖像處理器中,通用名稱為“Script-fu”。LIBREP是John Harper最初基於Emacs Lisp語言的Lisp解釋器,已嵌入Sawfish視窗管理器中。
語言創新
Lisp是第一種語言,其中程式代碼的結構忠實地直接表示在標準數據結構中 - 這種質量後來被稱為“同質性”。因此,Lisp函式可以在Lisp程式中進行操作,修改甚至創建,而無需進行低級操作。這通常被認為是該語言在其表達能力方面的主要優點之一,並使該語言適用於句法宏和元循環評估。
使用if-then-else語法的條件是由McCarthy在Fortran上下文中發明的。他提議將其納入ALGOL,但它不是Algol 58規範的一部分。對於Lisp,McCarthy使用了更為通用的cond結構。Algol 60接受了if-then-else並推廣它。
Lisp深深地影響了在Xerox PARC開發Smalltalk的研究團隊的領導者Alan Kay。反過來,Lisp受到了Smalltalk的影響,後來的方言在20世紀70年代採用了面向對象的編程特性(繼承類,封裝實例,訊息傳遞等)。 Flavors對象系統引入了多重繼承和mixin的概念。 Common Lisp對象系統提供多重繼承,具有多個分派的多方法和通用函式,從而產生靈活且強大的動態分派形式。它已成為許多後續Lisp(包括Scheme)對象系統的模板,這些對象系統通常通過元對象協定實現,這是一種反射式元葉設計,其中對象系統是根據自身定義的:Lisp只是Smalltalk之後的第二語言(並且仍然是極少數語言之一)擁有這樣的元對象系統。多年以後,Alan Kay建議,由於這些功能的融合,只有Smalltalk和Lisp可以被視為適當構思的面向對象編程系統。
Lisp引入了自動垃圾收集的概念,其中系統遍歷堆查找未使用的記憶體。現代複雜的垃圾收集算法(例如分代垃圾收集)的進步受到它在Lisp中的使用的刺激。
例子
以下是Common Lisp代碼的示例。
基本的“Hello world”程式:
(print "Hello world")
Lisp語法自然適用於遞歸。 在這種表示法中,諸如遞歸定義的集的枚舉之類的數學問題很容易表達。
評估一個數字的階乘:
(defun factorial (n) (if (= n 0) 1 (* n (factorial (- n 1)))))
如果底層Lisp系統最佳化尾遞歸,則替代實現比前一版本占用更少的堆疊空間:
(defun factorial (n &optional (acc 1)) (if (= n 0) acc (factorial (- n 1) (* acc n))))
與使用Common Lisp循環宏的疊代版本形成對比:
(defun factorial (n) (loop for i from 1 to n for fac = 1 then (* fac i) finally (return fac)))
以下功能可以反轉列表。Lisp的內置反向功能可以做同樣的事情。
(defun -reverse (list) (let ((return-value '())) (dolist (e list) (push e return-value)) return-value))