[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