Land Of Lisp 第4章
ここは条件文の章
if
条件文ifで空リストのみ偽と判定空リストの表現は4つある
例. '() () 'nil nil
(eq '() nil) t (eq '() ()) t (eq '() 'nil) t
例. 条件判定の例 リストの長さ
(defun my-length (list) (if list (1+ (my-length (cdr list))) 0)) my-length (my-length '(list with four symbols)) 4
listが変数名に使われていたが、
普通に使えるみたい。
その他条件の書き方
; 数値が等しい? (= 1 2) nil (= 1 1) t ; 奇数? (oddp 5) t ; 偶数? (evenp 5) nil
progn
if文の1つの分岐で複数の処理を実施例.
(if (oddp 5) (progn (setf *a* (+ 5 1)) 'odd) 'even) odd *a* 6
when
条件が真の場合に複数の処理を実施(暗黙のprogn)条件を見たさない場合はnilを返す。
例.
(when (oddp 5) (setf *b* 5) 'odd) odd *b* 5 (when (oddp 4) (setf *b* 5) 'odd) nil
unless
条件が偽の場合に複数の処理を実施(暗黙のprogn)条件を見たさない場合はnilを返す。
例.
(unless (oddp 4) (setf *c* 4) 'even) even *c* 4 (unless (oddp 5) (setf *c* 4) 'even) nil
cond
色々できる条件分岐例.偶数の数を返す(自作)
(defun make-even-number (num) (cond ((oddp num) (princ num) (princ " to ") (princ (+ num 1))) (t (princ num) (princ " is even number!")))) make-even-number (make-even-number 10) 10 is even number! " is even number!" (make-even-number 9) 9 to 10 10
t
真case
ほかの言語でもよく見るcase比較にはeqlが使われるので文字列では比較できないらしい。
例.
(defun what-is-in (x) (case x ((1) '(1 is in x)) ((A) '(A is in x)) (("A") '(""A"" is in x)) (otherwise '(what is this !)))) what-is-in (defvar *x* 1) *x* (what-is-in *x*) (1 is in x) (defparameter *x* 'A) *x* (what-is-in *x*) (A is in x) (defparameter *x* "A") *x* (what-is-in *x*) (what is this !)
テクニック
andとor
例.(and t t nil) nil (and t t t) t (or t t nil) t (or t t t) t
これらは、C#の短絡評価のように働く
例.
(or (oddp 4) '(it is even)) (it is even) (or (oddp 5) '(it is odd)) ; 後半は評価されない t (and (oddp 4) '(it is even)) ; 後半は評価されない nil (and (oddp 5) '(it is odd)) (it is odd)
こらは、できるというだけで真偽判定と処理は分けて書くのがよい。
member
リストの中に要素が含まれるか調べる返すのは見つかった要素以降の部分リスト
例.nil以外は真とみなされる
(if (member 1 '(3 4 1 5)) 'in 'no) in (member 1 '(3 4 1 5) (1 5)
find-if
条件付き検索関数には「#」をつける
例.
(find-if #'oddp '(2 4 5 6)) 5 ; ただしnullを使う場合は注意 (if (find-if #'null '(2 4 nil 6)) 'a 'b) b
比較関数
eq
シンボル同士の比較早い
equal
シンボル以外の比較eql
数値と文字を比較する(できる)equalp
文字の大小を区別しない、数値の整数、小数を区別しない、で比較する