[plt-scheme] Confusion about lexical scoping, modules, and hygenic macros

From: Danny Yoo (dyoo at hkn.eecs.berkeley.edu)
Date: Wed Aug 17 01:22:06 EDT 2005

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

(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))
> (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))
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!

Posted on the users mailing list.