以下がソース。
(define-macro (bind-rest rest binds . body)
(let loop ((binds binds))
(if (null? binds)
`(begin ,@body)
(let ((ret (loop (cdr binds)))
(bind (car binds)))
(let ((var (car bind))
(val (cadr bind)))
`(let ((,var (if (null? ,rest) ,val (car ,rest)))
(,rest (if (null? ,rest) rest (cdr ,rest))))
,ret))))))
使い方は、
(bind-rest リスト ((変数名 値)
...)
[手続き ...]
戻り値)
例:
(define (hoge a b . rest)
(bind-rest rest ((c 3)
(d 4))
(+ a b c d)))
(hoge 1 2)
-> 10
(hoge 1 2 4 8)
-> 15
もちろん値は関数の呼び出しでもいい。あと、restの余りはrestとして再度束縛されるので、bind-restを複数箇所で呼び出すこともできる。なので例えば処理の中で何か実行時の状況に依存する値取得(ユーザーからの入力とか)を行う関数があった場合に、単体テストの時だけその値を外部から引数で与えるとゆうことが簡単にできるわけ。
いじょう