単にマクロ展開のタイミングの話なのかな?
(import (rnrs)) (define (print x) (display x) (newline)) (define x 1) (define (incf x . i) (if (pair? i) (begin (set! x (+ x (car i))) (print "procedure") x) (begin (set! x (+ x 1)) (print "procedure") x))) (print (incf x 2)) (define (test x i) (print (incf x i))) (test x 1) (print "define incf as define-syntax!") (set! x 1) (define-syntax incf (syntax-rules () ((_ x) (begin (set! x (+ x 1)) x)) ((_ x i) (begin (set! x (+ x i)) x)))) (print (incf x 2)) (test x 1)こんなコードを、Chez(7.9.4)、Ypsilon(0.9.6-update3)、Mosh(0.2.5)に食わせてみる。
結果。
Chezは正常終了。最後の(test x 1)で展開されると思われてincfマクロは展開されず。
Ypisilonは最後の(test x 1)でincfの定義がない(多分、マクロで上書きされたから?)と怒る。
Moshはincfが複数定義されたといって例外。
それぞれの結果はこれ。
Chez
------------
procedure
3
procedure
2
define incf as define-syntax!
3
procedure
4
------------
Ypsilon
------------
procedure
3
procedure
2
define incf as define-syntax!
3
error: unbound variable incf
backtrace:
0 (incf x i)
..."D:/home/t.kato/test.scm" line 18
1 (test x 1)
..."D:/home/t.kato/test.scm" line 29
------------
mosh
------------
Condition components:
1. &who who: incf
2. &message message: "multiple definitions of identifier"
3. &syntax form: incf
subform: #f
Exception:
error in raise: returned from non-continuable exception
Stack trace:
1. throw:
2. (raise c): baselib.scm:943
3. apply:
------------
これだけバラバラだとどれが正しいのかわからない・・・
1 comment:
r6rs では再定義は禁止されています。
私の手元にある Petite Chez Scheme が 8.0 だったのでそれで試してみたところ「Exception: multiple definitions for incf in body」というエラーでした。
Ypsilon についても r6rs 準拠モード (コマンドラインオプションに -6 を付ける) では「error in top-level program: duplicate definitions」というエラーメッセージを出します。
Post a Comment