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> 式を、左から右に、真値 val(R6RS:翻訳: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 参照。