Next: , Previous: , Up: Control Structures   [Contents][Index]


10.2 Conditionals

条件による制御構造は、候補の中から選択を行ないます。Emacs Lispは4つの条件フォームをもちます。ifは他の言語のものとほとんど同じです。whenunlessは、ifの変種です。condは一般化されたcase命令です。

Special Form: if condition then-form else-forms…

ifは、conditionの値にもとづいて、then-formelse-formsを選択します。評価されたconditionが非nilの場合は、then-formが評価されて、その結果がreturnされます。それ以外は、else-formsがテキスト順に評価されて、最後のフォームの値がreturnされます(ifelseパートは、暗黙のprognの例です。Sequencingを参照してください)。

conditionの値がnilで、else-formsが与えられない場合、ifnilをreturnします。

選択されなかったブランチは決して評価されない — 無視される — ので、ifはスペシャルフォームです。したがって、以下の例ではprintは呼び出されることはないので、trueはプリントされません。

(if nil
    (print 'true)
  'very-false)
⇒ very-false
Macro: when condition then-forms…

これは、else-formsがなく、複数のthen-formsがあるかもしれない、ifの変種です。特に、

(when condition a b c)

は以下と完全に等価です

(if condition (progn a b c) nil)
Macro: unless condition forms…

これはthen-formがない、ifの変種です:

(unless condition a b c)

は以下と完全に等価です

(if condition nil
   a b c)
Special Form: cond clause…

condは、任意の数の候補から選択を行ないます。cond内の各clauseは、リストでなければなりません。このリストのCARconditionで、(もしあれば)残りの要素はbody-formsです。したがって、条項は以下のようになります:

(condition body-forms…)

condは、各条項のconditionを評価することにより、テキスト順で条項を試験します。conditionの値が非nilの場合、その条項は“成り立ち”ます。その後、condは、その条項のbody-formsを評価して、body-formsの最後の値をreturnします。残りの条項は無視されます。

conditionの値がnilの場合、その条項は“成り立たず”、condは次の条項に移動して、その条項のconditionを試験します。

以下のようなものも、条項になります:

(condition)

conditionがテストされたときに非nilなら、condフォームはconditionの値をreturnします。

すべてのconditionnilに評価された場合 — つまりすべての条項が不成立の場合、condnilをreturnします。

以下の例は4つの条項をもち、xの値が数字か、文字列化、バッファーか、シンボルかをテストします:

(cond ((numberp x) x)
      ((stringp x) x)
      ((bufferp x)
       (setq temporary-hack x) ; 1つの条項に
       (buffer-name x))        ; 複数bodyフォーム。
      ((symbolp x) (symbol-value x)))

前の条項が不成立のとき、最後の条項を実行したいときがよくあります。これを行なうには、(t body-forms)のように、conditionの最後の条項にtを使用します。フォームttに評価され、決してnilにならないので、この条項が不成立になることはなく、最終的にcondはこの条項に到達します。たとえば:

(setq a 5)
(cond ((eq a 'hack) 'foo)
      (t "default"))
⇒ "default"

このcond式は、aの値がhackの場合はfoo、それ以外は文字列"default"をreturnします。

任意の条件構成は、condifで表すことができます。したがって、どちらを選択するかは、スタイルの問題です、たとえば:

(if a b c)
≡
(cond (a b) (t c))