[plt-scheme] 299.32

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Feb 19 15:23:09 EST 2005

The exp-tagged code for MzScheme and MrEd in CVS is now version 299.32.

This version finally eliminates the "identifier for a definition has
a[nother] module context" error that sometimes results from a
macro-generating macro.

For example, the following definition of `define-get-and-set' is
perfectly reasonable:

   (module m mzscheme
     (provide define-get-and-set)
     (define-syntax define-get-and-set
       (syntax-rules ()
         [(_ get set v)
          (begin
            (define val v)
            (define (get) val)
            (define (set x) (set! val x)))])))

In some contexts, however, attempting to use `define-get-and-set' would
cause MzScheme to complain that the identifier `val' has the context of
`m', and therefore the identifier can't be defined in a different
context.

The usual workaround was to use `syntax-case' and generate a temporary
identifier for `val':

  (with-syntax ([(val) (generate-temporaries '(val))])
    ...)

In v209, even this workaround failed for uses of `define-get-and-set'
in the top-level environment.

The workaround is no longer necessary, and `define-get-and-set' will
work in any definition context.


Like many problems that take a long time to solve, this one has a
solution that seems obvious in retrospect. The module expander adds a
set of renamings to each body form *after* the form expanded far enough
to expose definitions (in addition to the initial remaning for the
whole module body, which carries imports, etc.). The post-expansion
renamings include only defined identifiers that were introduced by
macro expansion. In short, the module-expansion process is more similar
to that of internal definitions, where macros like `define-get-and-set'
have always worked.

Matthew



Posted on the users mailing list.