R6RS:翻訳:R6RS:11.4.5 Derived conditionals

R6RS:翻訳:R6RS:11.4.5 Derived conditionals

11.4.5 派生条件式

[syntax] (cond <cond clause1> <cond clause2> ...)

[auxiliary syntax] =>

[auxiliary syntax] else

構文: 各 <cond clause> は次のような形式をしていなければならない。

(<test> <expression1> ...)

ここで、 <test> は式である。代わりに、次の形式でもよい。

(<test> => <expression>)

最後の <cond clause> は「else 節」であってもよい。これは (else <expression1> <expression2> ...) という形式をしている。

意味論: cond 式は連続する <cond clause> の <test> のひとつが真値(R6RS:翻訳:R6RS:5.7 Boolean values 参照)を返すまで順に評価を進める。 <test> が真値を返すと <cond clause> の残りの式が順に評価されて、 <cond clause> の最後の式が cond 式全体の値として返る。選択された <cond clause> が <test> 式だけを含んでい、 <expression> がない場合には、結果として <test> の値が返る。選択された <cond clause> が => 代替形式を使っていた場合には、 <expression> が評価される。この式の値は手続きでなければならない。この手続きは引き数をひとつ取り、 <test> の値とともに呼び出されて、この手続きの返した値が cond 式から返される。 <test> がすべて #f に評価され、 else 節がない場合には条件式は未規定値を返す。 else 節がある場合にはその <expression> が評価され、最後のものの値が返される。

(cond ((> 3 2) ’greater)
      ((< 3 2) ’less))                 ⇒  greater

(cond ((> 3 3) ’greater)
      ((< 3 3) ’less)
      (else ’equal))                    ⇒  equal

(cond (’(1 2 3) => cadr)
      (else #f))                 ⇒  2

次の形式の <cond clause> のいずれかの場合、

(<test> <expression1> ...)
(else <expression1> <expression2> ...)

cond フォーム自体が末尾文脈にある場合には、最後の <expression> も末尾文脈になる。次の形式の <cond clause>

(<test> => <expression>)

では、 <expression> の評価結果による(暗黙の)手続き呼び出しもまた、 cond フォームが末尾文脈にあれば、末尾文脈内にある。

より単純なフォームによる cond の定義例は R6RS:翻訳:R6RS:B Sample definitions for derived forms にある。

(case <key> <case clause1> <case clause2> ...)

構文: <key> は式でなければならない。各 <case clause> は次の形式のいずれかでなければならない。

((<datum1> ...) <expression1> <expression2> ...)
(else <expression1> <expression2> ...)

(「else 節」を指定する」) 2 番目の形式は最後の <case clause> のとしてしか現れてはならない。各 <datum> は何らかのオブジェクトの外部表現である。 <datum> によって表されるデータには重複があってもかまわない。

意味論: case 式は次のように評価される。 <key> が評価されて、その結果が eqv? (R6RS:翻訳:R6RS:11.5 Equivalence predicates 参照) を使って、各 <case clause> の <datum> の表すデータと順に比較される。 <key> の評価結果が <case clause> の <datum> と等価であれば、対応する <expression> 群が左から右に評価され、 <case clause> 最後の式の値が case 式の結果として返る。さもなくは、比較処理が続けられて行く。 <key> の評価結果が各集合のどのデータとも異なった場合には、 else 節があった場合にはその式が評価されて最後の式の結果が case 式の値になる。そうでなければ、 case 式は未規定値を返す。

(case (* 2 3)
  ((2 3 5 7) ’prime)
  ((1 4 6 8 9) ’composite))             ⇒  composite
(case (car ’(c d))
  ((a) ’a)
  ((b) ’b))                             ⇒  unspecified
(case (car ’(c d))
  ((a e i o u) ’vowel)
  ((w y) ’semivowel)
  (else ’consonant))                    ⇒  consonant

case 式自体が末尾文脈にあれば <case clause> の最後の <expression> も末尾文脈内にある。 R6RS:翻訳:R6RS:11.20 Tail calls and tail contexts 参照。

[syntax] (and <test1> ...)

構文: <test> は式でなければならない。

意味論: <test> が存在しない場合には #t が返る。さもなくは、 <test> 式を、左から右へ、 <test> が #f を返すか、最後の <test> に到達するまで評価する。前者の場合 and 式は残りの式を評価せずに #f を返す。後者の場合、最後の式が評価されその値が返る。

(and (= 2 2) (> 2 1))                   ⇒  #t
(and (= 2 2) (< 2 1))                   ⇒  #f
(and 1 2 ’c ’(f g))                     ⇒  (f g)
(and)                                   ⇒  #t

and キーワードは syntax-rules を使って次のように定義することができる(R6RS:翻訳:R6RS:11.19 Macro transformers 参照)。

(define-syntax and
  (syntax-rules ()
    ((and) #t)
    ((and test) test)
    ((and test1 test2 ...)
     (if test1 (and test2 ...) #f))))

and 式が末尾文脈にある場合、最後の <test> 式も末尾文脈内にある。 R6RS:翻訳:R6RS:11.20 Tail calls and tail contexts 参照。

[syntax] (or <test1> ...)

構文: <test> は式でなければならない。

意味論: <test> が存在しない場合には #f が返る。それ以外の場合には、 <test> 式を、左から右に、真値 valR6RS:翻訳:R6RS:5.7 Boolean values 参照)が返るか、最後の <test> に到達に到達するまで評価する。前者の場合、 or 式は val を返し残りの式を評価しない。後者の場合、最後の式が評価されてその値が返る。

(or (= 2 2) (> 2 1))                    ⇒  #t
(or (= 2 2) (< 2 1))                    ⇒  #t
(or #f #f #f)         ⇒  #f
(or ’(b c) (/ 3 0))                     ⇒  (b c)

or キーワードは syntax-rules を使って次のように定義することができる(R6RS:翻訳:R6RS:11.19 Macro transformers 参照)。

(define-syntax or
  (syntax-rules ()
    ((or) #f)
    ((or test) test)
    ((or test1 test2 ...)
     (let ((x test1))
       (if x x (or test2 ...))))))

and 式が末尾文脈にある場合、最後の <test> 式も末尾文脈内にある。 R6RS:翻訳:R6RS:11.20 Tail calls and tail contexts 参照。

More ...