let-optionals*

Gauche には let-optionals* というマクロがある。 オプショナル引数を扱うのに便利なマクロだ。 詳しい仕様はマニュアルを見てもらいたい。
http://practical-scheme.net/gauche/man/?l=jp&p=let-optionals*
先日、 Twitterid:rg350 氏とやりとりしている中でこのマクロの話題が出た。 そこで自分で同等のものを書いてみようと考えた結果、思いがけず良い出来栄えになったので記事にすることにした。

(define-syntax let-optionals*
  (syntax-rules ()
    ((_ a ((v d) . r) . b)
     (let* ((t a)
            (v (if (null? t) d (car t))))
       (let-optionals* (if (null? t) '() (cdr t)) r . b)))
    ((_ a () . b)
     (begin . b))
    ((_ a (v . r) . b)
     (let-optionals* a ((v #f) . r) . b))
    ((_ a rv . b)
     (let ((rv a)) . b))))

R6RS 範囲内のつもりで書いている。 R5RS に対しては厳密には範囲外のはずだが、 Gauche や Chicken Scheme や Scheme48 では期待通りに動くので主要な処理系ならだいたい使えると思う。
ちなみにオリジナルは伝統的マクロで書かれているようだ。
http://gauche.svn.sourceforge.net/viewvc/gauche/Gauche/trunk/src/scmlib.scm?revision=7292&view=markup#l56
Document ID: 81d2f24842723898a500d42093b355e9