Andy Wingo <wi...@pobox.com> writes: >> (define foo 'module-a) >> (define-syntax alt-environment >> (syntax-rules () >> ((_) (the-environment)))) > >> and then evaluate the following within module B: > >> (define foo 'module-b) >> (local-eval 'foo (alt-environment)) > >> What should the result be? > >> My guess is that it should return 'module-a, because I think >> conceptually it should act as though the local-expression passed to >> `local-eval' were put in place of (the-environment), wherever that > > Dunno, I could make an argument either way :)
Having thought more about this, I'm fully convinced that 'module-a should be the answer. The real reason is that we need to macroexpand the new local expression within the expander-environment captured by (the-environment), and this expander-environment really determines the lexical environment that symbols are looked up in, in the same way that free variable references from a macro definition are resolved in the lexical environment of the macro definition instead of the place where the macro is used. If we don't use the expander-environment captured by (the-environment), what other expander-environment would we use, and how would we capture this other environment? I guess the other option would be that, if (the-environment) is found within a macro definition, then we should instead use the expander environment from where the currently-expanding macro was _used_. But what if that use is itself within another macro definition? I don't think it makes sense to just go up one level, that seems very inelegant. No, it should be one extreme or the other, so the other logical choice would be to go all the way up the macro expansion stack to the top, where the use of the _initial_ macro was found. But regardless of whether we go up one level or all the way to the top, this other option would cause serious problems. In the general case, (the-environment) could be nested quite deeply within `let's, `let-syntax's, and worse of all, `lambda's! For example, consider the following example: (define-syntax blah (syntax-rules () ((_) (lambda () (let-syntax (...) (let (<lots of variable definitions>) <lots of code> (the-environment))))))) If we were to use this crazy alternate rule, then `local-eval' should evaluate its expression in the environment where the above macro was used, i.e. where the procedure was _defined_. I hope we can all agree that this would be madness. No, the only sane option is to do the straightforward thing: we use the expander environment captured by (the-environment), even if that's found within a macro. And that also means that the module used by `local-eval' should be the module found within the expander environment, i.e. the module where the macro containing (the-environment) was _defined_. Does this make sense? Best, Mark