本節では、ifやcondとともに用いて複雑な条件を表現するために
しばしば使われる3つの構造を説明します。
andやorの構造は、
複数の条件付き構造の一種として単独で使うこともできます。
この関数は、conditionが偽であるかどうか調べる。 conditionが
nilであればtを返し、 さもなければnilを返す。 関数notはnullと同一であるが、 空リストかどうか調べる場合には、nullを使うことを勧める。
スペシャルフォーム
andは、 すべてのconditionsが真であるかどうか調べる。 conditionsを1つ1つ書かれた順に評価して調べる。conditionsのどれかが
nilに評価されると、andの結果は、残りのconditionsに関係なく、nilになる。 つまり、andはただちに完了し、 conditionsの残りを無視する。conditionsすべてが
nil以外であることがわかると、 それらの最後の値がフォームandの値となる。例を示そう。 最初の条件は整数1を返し、これは
nilではない。 同様に、2番目の条件は整数2を返し、nilではない。 3番目の条件はnilなので、残りの条件を評価しない。(and (print 1) (print 2) nil (print 3)) -| 1 -| 2 ⇒ nil
andを使ったより現実的な例はつぎのとおり。(if (and (consp foo) (eq (car foo) 'x)) (message "foo is a list starting with x"))
(consp foo)がnilを返すと(car foo)は実行されず、 そのためエラーを回避することに注意。
andは、ifやcondで表現できる。 たとえば、つぎのとおり。(and arg1 arg2 arg3) == (if arg1 (if arg2 arg3)) == (cond (arg1 (cond (arg2 arg3))))
スペシャルフォーム
orは、 conditionsの少なくとも1つが真であるかどうか調べる。 conditionsを1つ1つ書かれた順に評価して調べる。conditionsのどれかが
nil以外に評価されると、orの結果はnil以外になる。 そして、orはただちに完了し、 conditionsの残りを無視する。 戻り値は、nil以外に評価された値である。conditionsすべてが
nilであることがわかると、orはnilを返す。たとえば、つぎの式は、
xが0かnilであることを調べる。(or (eq x nil) (eq x 0))
and構造と同様に、orはcondで書き表せる。 たとえば、つぎのとおり。(or arg1 arg2 arg3) == (cond (arg1) (arg2) (arg3))
orをifで書くこともだいたいできるが、 途中で抜け出せない。(if arg1 arg1 (if arg2 arg2 arg3))これは完全には同一ではない。 というのは、arg1やarg2を2度評価するからである。 一方、
(orarg1 arg2 arg3)は、 どの引数も一度だけ評価する。