[plt-scheme] Confusion about lexical scoping, modules, and hygenic macros
Hi everyone,
I'm running into a puzzling problem ---here's a test case that shows
what's bothering me; from the toplevel, I wrote a small macro to play with
syntax-rules:
;;;;;;;
(module m1 mzscheme
(provide (all-defined))
(define-syntax arrow
(syntax-rules (->)
[(arrow -> x)
(list (quote x) 'arrowed!)])))
;;;;;;;
(Perhaps I've been watching too much Strong Bad. *grin*)
The following test shows what I expected:
;;;;;;;
> (module m2 mzscheme
(require m1)
(display (arrow -> this-is-from-m2))
(newline))
>
> (require m2)
(this-is-from-m2 arrowed!)
;;;;;;;
However, the following gives a very surprising result:
;;;;;;
> (module m3 mzscheme
(require (lib "contract.ss"))
(require m1)
(display (arrow -> this-is-from-m3))
(newline))
repl-2:4:11: arrow: bad syntax in: (arrow -> this-is-from-m3)
;;;;;;
I think I understand what's causing this. Somehow, during macro
expansion, the macro system's convinced that '->' is lexically bound, in
the same way that the canonically evil example:
;;;;;;
> (let ((else #f)) (cond [else 'do-you-see-me?]))
>
;;;;;;
shows what happens when macro keywords are bound lexically. But in the
example of m3, there's no "lexical" involved here, is there?
From the toplevel:
;;;;;;;;
> (define -> 'blah)
> (require m1)
> (arrow -> 'ok-please-break)
((quote ok-please-break) is arrowed!)
;;;;;;;;
This is what I expected out of m3 as well, and since my expectations were
violated, I'm interested in learning what I'm missing here. *grin*
Thanks for any help on this!