R7RSのparameterizeサンプル実装が不思議
よく見ると不思議でもなんでも無いけど。
R7RSに載っているparameterizeのサンプル実装が地味にシンプルな気がする。
(define-syntax parameterize (syntax-rules () ((parameterize ("step") ((param value p old new) ...) () body) (let ((p param) ...) (let ((old (p)) ... (new ((p <param-convert>) value)) ...) (dynamic-wind (lambda () (p <param-set!> new) ...) (lambda () . body) (lambda () (p <param-set!> old) ...))))) ((parameterize ("step") args ((param value) . rest) body) (parameterize ("step") ((param value p old new) . args) ;; ← ココ rest body)) ((parameterize ((param value) ...) . body) (parameterize ("step") () ((param value) ...) body))))
(cf. SRFI-39の実装 : http://srfi.schemers.org/srfi-39/srfi-39.html )
ココのp old newは、syntax-rules的なパターンで束縛されていない。これは、仮のシンボル3つを生成するために書いていて、すぐ↑のclauseに突入した時に、シンボルとして使われる。syntax-rulesでは、この方法で新しいシンボルを導入すると、他のsyntax-rules起動で挿入するシンボルとは被らないことが保証されている。
自分でsyntax-rulesを書くときもよく使うけど、他人に使われると結構読めない。
今、R7RSだけを読んでSchemeを作れるのか実験をしていて、R7RSに載っているサンプル実装をとりあえず入力してみたけど、ちょっと不思議な点が有る。
- case-lambdaが非常に唐突に出てくる。他のformは基本的に解説が先に来るのに。。せめてbinding-constructsのところに移動したほうが良い気がする。
- 他の手続きは基本的に(define x (lambda ...))で定義されているのに、make-parameterだけ、(define (make-parameter ...) ...)で定義されている。
規格書を読んで処理系を実装してみるのは、規格書の品質を向上するのに良い方法に思える。もうちょっと早くやっておけば良かった。