From: Matthew Flatt <mflatt@cs.utah.edu> To: plt-scheme@web-ext.cs.brown.edu Subject: [plt-scheme] 299.32 Date: Sat, 19 Feb 2005 13:23:09 -0700 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