摘自 《ANSI Common Lisp》
一、構建
cons函數可以用於構建列表,如:
CL-USER> (cons 'a 'b)
(A . B)
CL-USER> (cons 'a '(1 2 3))
(A 1 2 3)
CL-USER>
cons真正所做的事情是,把兩個對象結合成一個有兩部分的對象,稱之爲 Cons 對象。概念上來說,一個 Cons是一對指針;第一個是car,第二個是cdr。
列表可以嵌套,稱爲嵌套列表,如:
CL-USER> (cons '(a b c) '(1 2 3))
((A B C) 1 2 3)
而類似 (A 1 2 3) 則稱爲 平坦列表(flatlist)。
所有不是Cons 對象的東西,就是一個原子(atom)。注意:nil 即是一個原子也是一個列表。
二、等式
每一次調用cons ,Lisp會配置一塊新的內存給兩個指針。所以如果用同樣的參數調用兩次cons,實際上得到的是兩個不同的對象。
CL-USER> (eql (cons 'a nil) (cons 'a nil))
NIL
eql只有在兩個對象是同一個對象時才返回爲真。而equal在參數值相同時返回真。
三、映射函數
Common Lisp 提供了數個函數來對一個列表的元素做函數調用。最常使用的是mapcar,接受一個函數以及一個或多個列表,並返回把函數應用至每個列表的元素的結果,直到有的列表沒有元素爲止:
CL-USER> (mapcar #' (lambda (x) (+ x 1))
'( 1 2 3))
(2 3 4)
CL-USER> (mapcar #' list '(a b c) '(1 2 3 4))
((A 1) (B 2) (C 3))
maplist 接受同樣的參數,將列表的漸進的下一個cdr 傳入參數。
CL-USER> (maplist #' (lambda (x) x)
'(a b c))
((A B C) (B C) (C))
四、集合
member方法,返回指定的列表中指定的元素開始的部分。例如:
CL-USER> (member 'a '(a b c))
(A B C)
CL-USER> (member '2 '(1 2 3 4 5 6))
(2 3 4 5 6)
一般情況下,member使用 eql 來比較對象。你可以使用一種叫做關鍵字參數的東西來重寫缺省的比較方法。多數的 Common Lisp 函數接受一個或多個關鍵字參數。這些關鍵字參數不同的地方是,他們不是把對應的參數放在特定的位置作匹配,而是在函數調用中用特殊標籤,稱爲關鍵字,來作匹配。一個關鍵字是一個前面有冒號的符號。一個member函數所接受的關鍵字參數是 :test參數。如果你在調用member時,傳入某個函數作爲:test參數,那麼那個函數就會被用來比較是否相等,而不是用 eql。所以如果我們想找到一個給定的對象與列表中的成員是否相等(equal),我們可以:
> (member ' ( a ) ' ( ( a ) ( z ) ) :test # ' equal)
( ( A ) ( Z ) )
另一個member接受的關鍵字參數是:key參數。藉由提供這個參數,你可以在作比較之前,指定一個函數運用在每一個元素:
>(member ' a ' ((a b) (c d)) :key # ' car)
(( A B) (C D))
在這個例子裏,我們詢問是否有一個元素的car是a
如果我們想要找到一個元素滿足任意的判斷式像是──oddp ,奇數返回真──我們可以使用相關的member-if:
>(member-if #' oddp '(2 3 4))
(3 4)
函數adjoin像是條件式的 cons。它接受一個對象及一個列表,如果對象還不是列表的成員,才構建對象至列表上。
集合論中的並集 (union)、交集(intersection)以及補集(complement)的實現,是由函數union、intersection以及set-difference。
五、點狀列表(Dotted Lists)
調用list所構建的列表,準確的說稱之爲正規列表(properlist)。一個正規列表可以是nil 或是cdr是正規列表的 Cons 對象。
一個非正規列表的 Cons 對象稱之爲點狀列表 (dotted list)。如:
CL-USER> (cons 'a 'b)
(A . B)
六、關聯列表
用 Cons 對象來表示映射 (mapping)也是很自然的。一個由 Cons 對象組成的列表稱之爲關聯列表(assoc-list or alist)。這樣的列表可以表示一個翻譯的集合,舉例來說:
CL-USER> (setf trans '((+ . "add") (- . "subtract")))
((+ . "add") (- . "subtract"))
assoc用來取出在關聯列表中,與給定的鍵值有關聯的 Cons 對:
CL-USER> (assoc '+ trans)
(+ . "add")