Gauche には let-optionals* というマクロがある。 オプショナル引数を扱うのに便利なマクロだ。 詳しい仕様はマニュアルを見てもらいたい。
http://practical-scheme.net/gauche/man/?l=jp&p=let-optionals*
先日、 Twitter で id: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