次: Combining Conditions, 前: Sequencing, 上: Control Structures
条件付き制御構造は、選択肢を選びます。
Emacs Lispには、4つの条件付きフォームがあります。
他の言語のものとほとんど同じif、
ifの変形であるwhenやunless、
一般化したcase文であるcondです。
ifは、conditionをもとにして、 then-formかelse-formsを選ぶ。 conditionがnil以外に評価されると、 then-formを評価し、その結果を返す。 さもなければ、else-formsをテキスト上の順に評価し、 その最後のものの値を返す。 (ifのelse部分は、暗黙のprognの例である。 see Sequencing。)conditionが値
nilであり、かつ、else-formsがないと、ifはnilを返す。
ifがスペシャルフォームであるのは、 選択しなかった分岐をけっして評価しないからである。 したがって、つぎの例では、trueは表示されない。(if nil (print 'true) 'very-false) => very-false
これは
ifの変形であり、else-formsがなく、 then-formsは複数のフォームでもよい。 特に、(when condition a b c)は、つぎとまったく等価である。
(if condition (progn a b c) nil)
condは任意個数の選択肢から1つを選ぶ。condの各節clauseはリストである必要がある。 このリストのcarがcondition(条件)である。 残りの要素は、あれば、body-forms(本体フォーム)である。 つまり、各節はつぎのようになる。(condition body-forms...)
condは、各節のconditionを評価して、 各節をテキスト上の順に試す。 conditionの値がnil以外であれば、 その節は『成功』する。 そうすると、condはその節のbody-formsを評価し、 body-formsの最後の値がcondの値となる。 残りの節は無視する。conditionの値が
nilであると、 その節は『失敗』し、condはつぎの節へ移りそのconditionを試す。各conditionが
nilに評価されると、 すべての節が失敗し、condはnilを返す。節clauseは、つぎの形式でもよい。
(condition)この場合、conditionが
nil以外であると、 conditionがcondフォームの値になる。以下の例には4つの節があり、
xの値が、数、文字列、バッファ、シンボルかどうか調べる。(cond ((numberp x) x) ((stringp x) x) ((bufferp x) (setq temporary-hack x) ; 1つの節に (buffer-name x)) ; 複数個の本体フォーム ((symbolp x) (symbol-value x)))最後の節を除くそれよりまえの節がどれも成功しないときには、 最後の節を実行したいことがしばしばある。 これを行うには、
(tbody-forms)のように 最後の節のconditionにtを使う。 フォームtはtと評価され、けっしてnilではない。 そのため、condがこの節に達したときには、 この節が失敗することはない。たとえば、つぎのとおり。
(cond ((eq a 'hack) 'foo) (t "default")) => "default"この式は、
aの値がhackのときにはfooを返し、 さもなければ文字列"default"を返すcondである。
任意の条件付き構造は、condやifで表現できます。
したがって、どちらを使うかは好みの問題です。
たとえば、つぎのとおりです。
(if a b c)
==
(cond (a b) (t c))