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


11.2 条件

条件による制御構造は候補の中から選択を行ないます。Emacs Lispは5つの条件フォームをもちます。ifは他の言語のものとほとんど同じです。whenunlessifの変種です。condは一般化されたcase命令です。condを汎用化したものがpcaseです(Pattern-Matching Conditionalを参照)。

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

ifconditionの値にもとづきthen-formelse-formsを選択する。評価されたconditionが非nilならthen-formが評価されて結果がリターンされる。それ以外ならelse-formsがテキスト順に評価されて最後のフォームの値がリターンされる(ifelseパートは暗黙のprognの例である。Sequencingを参照)。

conditionの値がnilelse-formsが与えられなければ、ifnilをリターンする。

選択されなかったブランチは決して評価されない — 無視される — ので、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となる。したがってclauseは以下のようになる:

(condition body-forms…)

condは各clauseのconditionを評価することにより、テキスト順でclauseを試みる。conditionの値が非nilならそのclauseは成り立つ。その後にcondはそのclauseのbody-formsを評価して、body-formsの最後の値をリターンする。残りのclauseは無視される。

conditionの値がnilならそのclauseは失敗して、condは次のclauseに移動してそれのconditionを試みる。

clauseは以下のようにも見えるかもしれない:

(condition)

conditionがテストされたときに非nilなら、condフォームはconditionの値をリターンする。

すべてのconditionnilに評価された場合 — つまりすべてのclauseが不成立なら、condnilをリターンする。

以下の例はxの値が数字、文字列、バッファー、シンボルなのかをテストする4つのclauseをもつ:

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

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

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

このcond式はaの値がhackならfoo、それ以外は文字列"default"をリターンする。

すべての条件構文はcondifのいずれかで表すことができます。したがってどちらを選択するかはスタイルの問題になります。たとえば:

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