5

I understand that syntax-rules is a hygienic macro system, but I do not understand why this happens:

(define not (lambda (x) x))

(define-syntax nand
  (syntax-rules ()
    ((_ a b)
     (not (and a b)))))

(nand #f #t)

==> #f

Now, if I had redefined not after defining the macro, then (nand #f #t) returns #t. Why, if the macro system is supposed to be hygienic?

josh
  • 997
  • 1
  • 8
  • 13

1 Answers1

5

The macro is expanded in the environment that existed at the time the macro was defined, not in the environment that existed at the time the macro was called. This has nothing to do with hygiene, which is the property that variables introduced by the macro are distinct from other variables with the same name that exist elsewhere in the program.

user448810
  • 17,381
  • 4
  • 34
  • 59
  • 4
    This question is also bleeding over into questions about the top-level environment. In Racket, for instance, you'll get #f either way, because the definition of 'not' is in scope for all of the module. Like @user448810 said, though, this is not a question about hygiene. – John Clements Jan 19 '12 at 17:38
  • 2
    @user448810 - "This has nothing to do with hygiene" - That is not entirely correct. In practice, referential transparency (which is what the question is really asking about) is generally referred to as a property of hygienic macros. See: http://community.schemewiki.org/?scheme-faq-macros – Justin Ethier Jan 24 '12 at 16:09