R6RS では import した変数に set! することは出来ない。 明示的な import であろうと暗黙の import であろうと関係なく set! できない。
そこをなんとか set! できる (かの) ようにするマクロを書こうとしたのが前回の記事だ。
http://saito.hatenablog.jp/entry/2012/09/08/091259
どうしてエラーになるのかわからずにおり、健全マクロのリネームが関係していると予想していたのだが、コメントで指摘をもらって確認したところ、 import した変数に set! できないだけでなく export した変数にも set! できないという制約の存在があることがわかった。
こういった構文違反の場合には &syntax コンディション型の例外を発生させることになっている (R6RS 5.5 Syntax violations) ので、実行できてしまった Racket と Ypsilon の挙動が R6RS 的には違反ということになるのだろう。
とりあえずこの挙動を踏まえて、 define-settable を書き直してみた。
#!r6rs (library (settable-variable) (export define-settable) (import (rnrs)) (define-syntax define-settable (syntax-rules () ((_ var val) (begin (define dummy val) (define (set-dummy! x) (set! dummy x)) (define (dummy-ref) dummy) (define-syntax var (make-variable-transformer (lambda(x) (syntax-case x (set!) ((set! _ a) #'(set-dummy! a)) (_ #'(dummy-ref)))))))))) )
Document ID: 343406d8aa951219f764a3e7ab850083