Lisp介紹之七個原始操作符
本文是paul graham所著的《Lisp之根源》的第一部分,在對Lisp的介紹中,描述了Lisp中的七個原始操作符。這是一篇非常不錯的Lisp介紹文,值得一讀。
約翰麥卡錫于1960年發表了一篇非凡的論文,他在這篇論文中對編程的貢獻有如歐幾里德對幾何的貢獻.1 他向我們展示了,在只給定幾個簡單的操作符和一個表示函數的記號的基礎上, 如何構造出一個完整的編程語言. 麥卡錫稱這種語言為Lisp, 意為List Processing, 因為他的主要思想之一是用一種簡單的數據結構表(list)來代表代碼和數據.
值得注意的是,麥卡錫所作的發現,不僅是計算機史上劃時代的大事, 而且是一種在我們這個時代編程越來越趨向的模式.我認為目前為止只有兩種真正干凈利落, 始終如一的編程模式:C語言模式和Lisp語言模式.此二者就象兩座高地, 在它們中間是尤如沼澤的低地.隨著計算機變得越來越強大,新開發的語言一直在堅定地趨向于Lisp模式. 二十年來,開發新編程語言的一個流行的秘決是,取C語言的計算模式,逐漸地往上加Lisp模式的特性,例如運行時類型和無用單元收集.
在這篇文章中我盡可能用最簡單的術語來解釋約翰麥卡錫所做的發現. 關鍵是我們不僅要學習某個人四十年前得出的有趣理論結果, 而且展示編程語言的發展方向. Lisp的不同尋常之處--也就是它優質的定義--是它能夠自己來編寫自己. 為了理解約翰麥卡錫所表述的這個特點,我們將追溯他的步伐,并將他的數學標記轉換成能夠運行的Common Lisp代碼.
七個原始操作符
開始我們先定義表達式 .表達式或是一個原子 (atom),它是一個字母序列(如 foo),或是一個由零個或多個表達式組成的表 (list), 表達式之間用空格分開, 放入一對括號中. 以下是一些表達式:
- foo
- ()
- (foo)
- (foo bar)
- (a b (c) d)
最后一個表達式是由四個元素組成的表, 第三個元素本身是由一個元素組成的表.
在算術中表達式 1 + 1 得出值2. 正確的Lisp表達式也有值. 如果表達式e 得出值v ,我們說e 返回 v . 下一步我們將定義幾種表達式以及它們的返回值.
如果一個表達式是表,我們稱第一個元素為操作符 ,其余的元素為自變量 .我們將定義七個原始(從公理的意義上說)操作符: quote,atom,eq,car,cdr,cons,和 cond.
(quote x ) 返回x .為了可讀性我們把(quote x )簡記 為'x . Lisp代碼
- > (quote a)
- a
- > 'a
- a
- > (quote (a b c))
- (a b c)
(atom x )返回原子t如果x 的值是一個原子或是空表,否則返回(). 在Lisp中我們按慣例用原子t表示真, 而用空表表示假. Lisp代碼
- > (atom 'a)
- t
- > (atom '(a b c))
- ()
- > (atom '())
- t
既然有了一個自變量需要求值的操作符, 我們可以看一下quote的作用. 通過引用(quote)一個表,我們避免它被求值. 一個未被引用的表作為自變量傳給象 atom這樣的操作符將被視為代碼:
- > (atom (atom 'a))
- t
反之一個被引用的表僅被視為表, 在此例中就是有兩個元素的表:
- > (atom '(atom 'a))
- ()
這與我們在英語中使用引號的方式一致. Cambridge(劍橋)是一個位于麻薩諸塞州有90000人口的城鎮. 而``Cambridge''是一個由9個字母組成的單詞.
引用看上去可能有點奇怪因為極少有其它語言有類似的概念. 它和Lisp最與眾不同的特征緊密聯系:代碼和數據由相同的數據結構構成, 而我們用quote操作符來區分它們.
(eq x y )返回t如果x 和y 的值是同一個原子或都是空表, 否則返回(). Lisp代碼
- > (eq 'a 'a)
- t
- > (eq 'a 'b)
- ()
- > (eq '() '())
- t
(car x )期望x 的值是一個表并且返回x 的第一個元素. Lisp代碼
- > (car '(a b c))
- a
(cdr x )期望x 的值是一個表并且返回x 的第一個元素之后的所有元素.
- > (cdr '(a b c))
- (b c)
(cons x y )期望y 的值是一個表并且返回一個新表,它的第一個元素是x 的值, 后面跟著y 的值的各個元素. Lisp代碼
- > (cons 'a '(b c))
- (a b c)
- > (cons 'a (cons 'b (cons 'c '())))
- (a b c)
- > (car (cons 'a '(b c)))
- a
- > (cdr (cons 'a '(b c)))
- (b c)
(cond ( ... ) ...( ... )) 的求值規則如下. p 表達式依次求值直到有一個返回t. 如果能找到這樣的p 表達式,相應的e 表達式的值作為整個cond表達式的返回值.
- > (cond ((eq 'a 'b) 'first)
- ((atom 'a) 'second))
- second
當表達式以七個原始操作符中的五個開頭時,它的自變量總是要求值的.2 我們稱這樣 的操作符為函數 .
以上就是Lisp介紹中有關其他原始操作符的描述。
【編輯推薦】