[gambit-list] Hygienic macros failing?
Taylor R Campbell
campbell at mumble.net
Sun Aug 19 19:21:19 EDT 2007
Date: Sat, 18 Aug 2007 23:29:19 -0400 (CLT)
From: "andrew cooke" <andrew at acooke.org>
(define-syntax bad
(syntax-rules ()
((_ (arg1 ...) (arg2 ...))
(receive (a b c) (values arg1 ...)
(newline)
(write (list arg2 ...))))))
(receive (a b c) (values 1 2 3) (bad (7 8 9) (a b c)))
This displays (7 8 9) when arg2 should be (1 2 3) (the value of a b c in
the calling code, not the value in "bad").
This is because Gambit runs two macro expanders over the code: the
SYNTAX-CASE expander (hygienic), and then the evaluator's own
non-hygienic expander. To SYNTAX-CASE, RECEIVE looks like a variable
reference, not a binding form, so it doesn't recognize that A, B, and
C are to be bound to distinct variables in the two distinct uses of
RECEIVE. Then the evaluator's non-hygienic expander actually expands
the RECEIVE to a call to CALL-WITH-VALUES (or the ridiculously
octothorped version thereof), and the variables are captured.
Try this before running the example:
(define-syntax receive
(syntax-rules ()
((RECEIVE bvl expression body0 body1 ...)
(CALL-WITH-VALUES (LAMBDA () expression)
(LAMBDA bvl body0 body1 ...)))))
Then RECEIVE will be a hygienic macro, and the SYNTAX-CASE expander
should rename the variables introduced by BAD accordingly.
More information about the Gambit-list
mailing list