[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
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!



Posted on the users mailing list.