次: Iteration, 前: Conditionals, 上: Control Structures
本節では、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)は、 どの引数も一度だけ評価する。