[plt-scheme] 299.32
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