次: 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)))最後の節を除くそれよりまえの節がどれも成功しないときには、 最後の節を実行したいことがしばしばある。 これを行うには、
(t
body-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))