Lisp語(yǔ)言誕生的時(shí)候就包含了9種新思想。其中一些我們今天已經(jīng)習(xí)以為常,另一些則剛剛在其他高級(jí)語(yǔ)言中出現(xiàn),至今還有2種是 Lisp 獨(dú)有的。按照被大眾接受的程度,這9種思想依次如下排列。
(1) 條件結(jié)構(gòu)(即 if-then-else 結(jié)構(gòu))?,F(xiàn)在大家都覺(jué)得這是理所當(dāng)然的,但是 Fortran I 就沒(méi)有這個(gè)結(jié)構(gòu),它只有基于底層機(jī)器指令的 goto 結(jié)構(gòu)。 (2) 函數(shù)也是一種數(shù)據(jù)類型。在 Lisp 語(yǔ)言中,函數(shù)與整數(shù)或字符串一樣,也屬于數(shù)據(jù)類型的一種。它有自己的字面表示形式(literal representation),能夠存儲(chǔ)在變量中,也能當(dāng)作參數(shù)傳遞。一種數(shù)據(jù)類型應(yīng)該有的功能,它都有。 (3) 遞歸。Lisp 是第一種支持遞歸函數(shù)的高級(jí)語(yǔ)言。 (4) 變量的動(dòng)態(tài)類型。在 Lisp 語(yǔ)言中,所有變量實(shí)際上都是指針,所指向的值有類型之分,而變量本身沒(méi)有。復(fù)制變量就相當(dāng)于復(fù)制指針,而不是復(fù)制它們指向的數(shù)據(jù)。 (5) 垃圾回收機(jī)制。 (6) 程序由表達(dá)式組成。Lisp 程序是一些表達(dá)式樹的集合,每個(gè)表達(dá)式都返回一個(gè)值。這與 Fortran 和大多數(shù)后來(lái)的語(yǔ)言都截然不同,它們的程序由表達(dá)式和語(yǔ)句組成。 區(qū)分表達(dá)式和語(yǔ)句在 Fortran I 中是很自然的,因?yàn)樗恢С终Z(yǔ)句嵌套。所以,如果你需要用數(shù)學(xué)式子計(jì)算一個(gè)值,那就只有用表達(dá)式返回這個(gè)值,沒(méi)有其他語(yǔ)法結(jié)構(gòu)可用,否則就無(wú)法處理這個(gè)值。 后來(lái),新的編程語(yǔ)言支持塊結(jié)構(gòu),這種限制當(dāng)然也就不存在了。但是為時(shí)已晚,表達(dá)式和語(yǔ)句的區(qū)分已經(jīng)根深蒂固。它從 Fortran 擴(kuò)散到 Algol 語(yǔ)言,接著又?jǐn)U散到它們兩者的后繼語(yǔ)言。 (7) 符號(hào)類型。符號(hào)實(shí)際上是一種指針,指向存儲(chǔ)在散列表中的字符串。所以,比較兩個(gè)符號(hào)是否相等,只要看它們的指針是否一樣就行了,不用逐個(gè)字符地比較。 (8) 代碼使用符號(hào)和常量組成的樹形表示法。 (9) 無(wú)論什么時(shí)候,整個(gè)語(yǔ)言都是可用的。Lisp 并不真正區(qū)分讀取期、編譯期和運(yùn)行期。你可以在讀取期編譯或運(yùn)行代碼,也可以在編譯期讀取或運(yùn)行代碼,還可以在運(yùn)行期讀取或者編譯代碼。 在讀取期運(yùn)行代碼,使得用戶可以重新調(diào)整(reprogram)Lisp 的語(yǔ)法;在編譯期運(yùn)行代碼,則是 Lisp 宏的工作基礎(chǔ);在運(yùn)行期編譯代碼,使得 Lisp 可以在 Emacs 這樣的程序中充當(dāng)擴(kuò)展語(yǔ)言(extension language);在運(yùn)行期讀取代碼,使得程序之間可以用S表達(dá)式(S-expression)通信,近來(lái) XML 格式的出現(xiàn)使得這個(gè)概念被重新“發(fā)明”出來(lái)了。 Lisp 語(yǔ)言剛出現(xiàn)的時(shí)候,這些思想與其他編程語(yǔ)言大相徑庭,后者的設(shè)計(jì)思想主要由50年代后期的硬件決定。隨著時(shí)間流逝,流行的編程語(yǔ)言不斷更新?lián)Q代,語(yǔ)言設(shè)計(jì)思想逐漸向 Lisp 靠攏。思想(1)到思想(5)已經(jīng)被廣泛接受,思想(6)開始在主流編程語(yǔ)言中出現(xiàn),思想(7)在 Python 語(yǔ)言中有所實(shí)現(xiàn),不過(guò)似乎沒(méi)有專用的語(yǔ)法。 思想(8)可能是最有意思的一點(diǎn)。它與思想(9)只是由于偶然原因才成為 Lisp 語(yǔ)言的一部分,因?yàn)樗鼈儾粚儆邴溈ㄥa的原始構(gòu)想,是由拉塞爾自行添加的。它們從此使得 Lisp 語(yǔ)言看上去很古怪,但也成為了這種語(yǔ)言最獨(dú)一無(wú)二的特點(diǎn)。說(shuō) Lisp 語(yǔ)言古怪倒不是因?yàn)樗恼Z(yǔ)法很古怪,而是因?yàn)樗緵](méi)有語(yǔ)法,程序直接以解析樹(parse tree)的形式表達(dá)出來(lái)。在其他語(yǔ)言中,這種形式只是經(jīng)過(guò)解析在后臺(tái)產(chǎn)生,但是 Lisp 直接采用它作為表達(dá)形式。它由列表構(gòu)成,而列表則是 Lisp 的基本數(shù)據(jù)結(jié)構(gòu)。 用一門語(yǔ)言自己的數(shù)據(jù)結(jié)構(gòu)來(lái)表達(dá)該語(yǔ)言是非常強(qiáng)大的功能。思想(8)和思想(9),意味著你可以寫出一種能夠自己編程的程序。這可能聽起來(lái)很怪異,但是對(duì)于 Lisp 語(yǔ)言卻是再普通不過(guò)。最常用的做法就是使用宏。 術(shù)語(yǔ)“宏”在 Lisp 語(yǔ)言中的意思與其他語(yǔ)言中的不一樣。Lisp 宏無(wú)所不包,它既可能是某樣表達(dá)式的縮略形式,也可能是一種新語(yǔ)言的編譯器。無(wú)論是想真正理解 Lisp 語(yǔ)言,還是只想拓寬編程視野,最好都學(xué)學(xué)宏。就我所知,宏(采用 Lisp 語(yǔ)言的定義)目前仍然是 Lisp 獨(dú)有的。一個(gè)原因是為了使用宏,你大概不得不讓你的語(yǔ)言看上去像 Lisp 一樣古怪。另一個(gè)可能的原因是,如果你想為自己的語(yǔ)言添上這種終極武器,你從此就不能聲稱自己發(fā)明了新語(yǔ)言,只能說(shuō)發(fā)明了一種 Lisp 的新方言。 我把這件事當(dāng)作笑話說(shuō)出來(lái),但是事實(shí)就是如此。如果你創(chuàng)造了一種新語(yǔ)言,其中有 car、cdr、cons、quote、cond、atom、eq 這樣的功能,還有一種把函數(shù)寫成列表的表示方法,那么在它們的基礎(chǔ)上完全可以推導(dǎo)出 Lisp 語(yǔ)言的所有其他部分。事實(shí)上,Lisp 語(yǔ)言就是這樣定義的,麥卡錫把語(yǔ)言設(shè)計(jì)成這個(gè)樣子就是為了讓這種推導(dǎo)成為可能。 |
|
來(lái)自: 昵稱10804835 > 《AutoLisp/VLisp》