For Gauche 0.9.5


Next: , Previous: , Up: 基本的な構文   [Contents][Index]

4.5 条件式

Special Form: if test consequent alternative
Special Form: if test consequent

[R7RS] まずtestを評価し、それが真の値を返したらconsequentを評価します。 そうでなければalternativeを評価します。もしalternativeが与えられて いなければ未定義の値を返します。

(if (number? 3) 'yes 'no) ⇒ yes
(if (number? #f) 'yes 'no) ⇒ no

(let ((x '(1 . 2)))
  (if (pair? x)
      (values (car x) (cdr x))
      (values #f #f)))
  ⇒ 1 and 2
Special Form: cond clause1 clause2 …

[R7RS][SRFI-61] 各clause節は次のいずれかの形式でなければなりません。

(test expr …)
(test => expr)
(test guard => expr)
(else expr expr2 …)

最後の形式は最後の節のみに許されます。

最初の節から順にtestが評価され、それが真の値を返すまで次の節のtestが 評価されます。testが真の値を返したら、それが最初の形式であれば その節のexprが順に評価され、最後の評価値が戻り値となります。 それが2番目の形式であれば、exprがまず評価されます。 exprは引数をひとつ取る手続きを返さねばなりません。 続いて、testの結果がその手続きに渡され、その手続きの戻り値がcond形式の 評価値となります。

3番目の形式はSRFI-61で定義されています。この形式では、testは 任意の数の値に評価されることができます。それらの値がまず guardに渡され、もしguardが真の値を返したら、同じ引数がexprに 適用されて、その戻り値がcond形式の評価値となります。 guard#fを返した場合は次の節へと評価が進みます。 guardexpr は、testが返すのと同数の引数を取れなければいけません。

もし全てのテストが偽の値を返し、最後の節が4番目の形式(else節)でなければ、未定義の値が返されます。

最後の節がelse節で、他の全てのテストが失敗した場合、else節のexpr が順に評価され、その最後の値がcond形式の値となります。

(cond ((> 3 2) 'greater)
      ((< 3 2) 'less)) ⇒ greater
(cond ((> 3 3) 'greater)
      ((< 3 3) 'less)
      (else 'equal)) ⇒ equal
(cond ((assv 'b '((a 1) (b 2))) => cadr)
      (else #f)) ⇒ 2
Special Form: case key clause1 clause2 …

[R7RS][SRFI-87] keyは任意の式です。clauseは以下の形式でなければなりません。

((datum ...) expr expr2 …)
((datum ...) => proc)

ここで、各datumはSchemeオブジェクトの外部表現であり、全てのdatumは 異なっていなければなりません。最後のclauseには次の形式を持つelse節が許されます。

(else expr expr2 …)
(else => proc)

まずkeyが評価され、その結果がそれぞれのdatumと比較されます。 keyの値とeqv?(等価参照)を使って一致するdatum が見つかれば、対応するexprが順に評価され、その最後の値がcaseの 値となります。=>を含む節はSRFI-87で定義されています。これらの節では、 keyの結果がprocに渡され、その結果がcaseの値となります。

もし一致するdatumが見つからない場合、else節が与えられていれば そのexprが順に評価され、最後の値が返されます。else節がなければcase節 の値は未定義です。

(case (* 2 3)
  ((2 3 5 7) 'prime)
  ((1 4 6 8 9) 'composite)) ⇒ composite

(case (car '(c d))
  ((a) 'a)
  ((b) 'b)) ⇒ undefined

(case (car '(c d))
  ((a e i o u) 'vowel)
  ((w y) 'semivowel)
  (else 'consonant)) ⇒ consonant

(case 6
  ((2 4 6 8) => (cut + <> 1))
  (else => (cut - <> 1))) ⇒ 7

(case 5
  ((2 4 6 8) => (cut + <> 1))
  (else => (cut - <> 1))) ⇒ 4
Macro: ecase key clause1 clause2 …

このフォームはほぼcaseと同等ですが、else節が与えられず、 keyの値がclause中のどのdatumとも一致しなかった場合の 動作だけが異なります。caseではそのような場合は未定義値が返されますが、 ecaseはエラーを報告します。

このマクロはCommon Lispから採られました。想定外の値が渡されることを 念のために検出したい、という場合に便利です。

(ecase 5 ((1) 'a) ((2 3) 'b) ((4) 'c))
 ⇒ ERROR: ecase test fell through: got 5, expecting one of (1 2 3 4)
Special Form: and test …

[R7RS] test式が順に評価されます。最初に偽の値を返したところで評価が止まり、 偽の値が返されます。残りの式は評価されません。 もし全ての式が真の値を返した場合は、最後の式の値が返されます。 式が与えれない場合は#tが返されます。

(and (= 2 2) (> 2 1)) ⇒ #t
(and (= 2 2) (< 2 1)) ⇒ #f
(and 1 2 'c '(f g))   ⇒ (f g)
(and)                 ⇒ #t
Special Form: or test …

[R7RS] test式が順に評価されます。最初に真の値を返したところで評価が止まり、 その値が返されます。残りの式は評価されません。 もし全ての式が偽の値を返した場合は、偽の値が返されます。 式が与えれない場合は#fが返されます。

(or (= 2 2) (> 2 1)) ⇒ #t
(or (= 2 2) (< 2 1)) ⇒ #t
(or #f #f #f)        ⇒ #f
(or (memq 'b '(a b c))
    (/ 3 0)) ⇒ (b c)
Special Form: when test expr1 expr2 …
Special Form: unless test expr1 expr2 …

[R7RS] まずtestが評価されます。それが真の値(unlessの場合は偽の値)を返した場合、 引続きexpr1およびexpr2 …が順に評価され、最後の評価値が返されます。 そうでなければ、未定義の値が返されます。


Next: , Previous: , Up: 基本的な構文   [Contents][Index]