表題

case 節における =>

著者

Chongkai Zhu

状態

この SRFI は現在「確定」の状態である。 SRFI の各状態の説明については ここ を参照せよ。 この SRFI に関して議論したいなら、 mailto:srfi minus 87 at srfi dot schemers dot org にメールを送信してください。 このメーリングリストに参加する方法については ここの説明 を参照せよ。 この SRFI に関する議論については メーリングリストのアーカイブ を参照せよ。 この SRFI に関する確定後の議論については メーリングリストのアーカイブ を参照せよ。

概要

本 SRFI では、case 構文を拡張して cond のような => 節を導入することを提案する。

論拠

casecond に対する構文シュガーとして導入された。 この構文を使うと let を明示的に呼び出す必要がなくなるという利点がある。 しかし、=> 節がないので、 result 式が key を必要とする場合は let を記述しないといけなくなる。 以下に簡単な例をあげよう。
(case (get-symbol)
  ((true) #t)
  ((false) #f)
  (else => (lambda (x) x)))

この式は、case=> 節がなければ、 次のように書かなければならない。

(let ((key (get-symbol)))
  (cond ((eq? key 'true) #t)
        ((eq? key 'false) #f)
        (else key)))

仕様

(R5RS 4.2.1 節『条件式』をベースにしている)

library syntax: case <key> <clause1> <clause2> ...

構文: <key> は任意の式である。 各 <clause> は

((<datum1> ...) <expression1> <expression2> ...)
という形式でなければならない。

ここで各 <datum> は何らかのオブジェクトの外部表現である。 すべての <datum> は異なる値でなければならない。 最後の <clause> は「else 節」とすることができ、その形式は次のようにする。

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

上記の形式の代わりに、<clause> は次の形式でもよい。

((<datum1> ...) => <expression>)

また、最後の <clause> は次の形式でもよい。

(else => <expression>)

意味論: `case' 式は以下のように評価される。 まず <key> が評価され、その結果が各 <datum> と比較される。 <key> の評価結果が (`eqv?' の意味で (『6.1 等価述語』を参照) ) <datum> に等しい場合、それに対応する <clause> の式が左から右の順に評価され、 <clause> の最後の式の結果が `case' 式の結果として返される。 <key> の評価結果がどの <datum> とも異なる場合は、 else 節が存在すればその式が評価されて、その最後の式の結果が `case' 式の結果として返される。 else 節が存在しなければ、`case' 式の値は不定値になる。 選択された <clause> が => 形式を使用している場合は、 その <expression> が評価される。 その値は1個の引数を受け取る手続きでなければならない。 次に、 <key> の値を引数にしてこの手続きが呼び出され、 その戻り値が `case' 式の結果として返される。

(R5RS 3.5 節『真の末尾再帰』をベースにしている)

cond または case 式が末尾コンテキストにあって、 (<expression1> => <expression2>) の形式の節を持つ場合、 <expression2> の評価結果として返される手続きの (暗黙的な) 呼び出しは、 末尾コンテキストにある。 <expression2> それ自身は末尾コンテキストにはない。

実装

(define-syntax case
  (syntax-rules (else =>)
    ((case (key ...)
       clauses ...)
     (let ((atom-key (key ...)))
       (case atom-key clauses ...)))
    ((case key
       (else => result))
     (result key))
    ((case key
       ((atoms ...) => result))
     (if (memv key '(atoms ...))
         (result key)))
    ((case key
       ((atoms ...) => result)
       clause clauses ...)
     (if (memv key '(atoms ...))
         (result key)
         (case key clause clauses ...)))
    ((case key
       (else result1 result2 ...))
     (begin result1 result2 ...))
    ((case key
       ((atoms ...) result1 result2 ...))
     (if (memv key '(atoms ...))
         (begin result1 result2 ...)))
    ((case key
       ((atoms ...) result1 result2 ...)
       clause clauses ...)
     (if (memv key '(atoms ...))
         (begin result1 result2 ...)
         (case key clause clauses ...)))))

著作権

Copyright (C) 2006 Chongkai Zhu. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


編集者: Mike Sperber
最終更新日時: Mon Apr 10 21:20:25 CEST 2006