摘自 《Lisp語言- 陳光喜》
一、條件
在Lisp中用原子t 表示真,nil表示假。 一般說來,函數名以字母 p 的 lisp 函數用於檢驗對象具有某種屬性。例如,symbolp,listp,keywordp,boundp,fboundp,numberp,typep,oddp,evenp,zerop。
像這一類返回值爲真或假的函數稱爲微詞 predicate 。
1、typep 用於測試某個對象是否具有指定的類型。
如:> (typep 12 'integer)
> T
2、用於條件測試的函數包括 eq,,>,<,= 等等。邏輯聯結詞有 not,and,or 含義分別爲非,且,或。
(1)Common Lisp 中最簡單的條件操作符是 if,用法如下: (if test exp1 exp2)
如:> (if (listp (cons 'a nil)) (* 2 3) (* 3 3))
> 6
表達式 exp2 可以省略。但是如果此時 test 值爲假,則整個表達式返回
nil。
> (if (> 3 2) (format nil " ~A > ~A" 3 2))
" 3 > 2"
> (if (< 3 2) (format nil " ~A > ~A" 3 2))
NIL
需要注意的是,exp1和exp2都是單一表達式。如果需要使用多個表達式完成多個處理,可以使用progn。用法是:
(progn
exp21
exp2
...
exp2k)
它將這k個表達式組合成一個表達式。
二、循環
do 是最基本最重要的循環操作符。Do 與 let 類似,可以定義局部變量。標準用法如下:
(do ((var1 init1 updt1) (var2 init2 updt2) …(varn initn updtn))
(endtest exp1 exp2 … expk)
exps)
其中 var1,…,varn 是循環變量,init1,…,initn 是循環變量對應的初值表達式;updt1,…,updtn是變量每個循環步循環變量修改爲的新值,允許省略,若該值省略,則對應循環變量不重新賦值;endtest 是循環終止的測試條件,若其值爲 nil,循環繼續進行,執行循環體 exps;否則,順次執行結果語句組
exp1,…,expk,並返回 expk 的值,循環終止。
例1,計算1到10的平方:
CL-USER> (let ((b nil))
(do ((a 1 (+ a 1)))
((> a 10) b)
(setf b (cons (* a a) b )))
)
(100 81 64 49 36 25 16 9 4 1)
對於表 list 中元素的循環處理,Common Lisp 提供了一種更簡潔的循環方式。用法如下:
(dolist (var list result)
exps)
其中 var 是循環變量,它每個循環步順次取 list 中的值。 result 是一個表達式,循環終止時將 result的值作爲循環語句返回值。exps 爲循環體。
例2,計算1到10的平方根之和:
CL-USER> (let ((b '(1 2 3 4 5 6 7 8 9 10))(c 0) d)
(dolist (v b c)
(setf d (sqrt v))
(setf c (+ c d))))
22.468277
例3,計算1到10之和:
CL-USER>(let ((a '(1 2 3 4 5 6 7 8 9 10))(b 0))
(dolist (v a b)
(setf b (+ v b))))
55