Hi Florian, "pelzflorian (Florian Pelz)" <pelzflor...@pelzflorian.de> writes:
> I am writing a Guile macro to manipulate Scheme code and am stuck on > what I hope is a simple problem and it would be nice if you could > explain. I try: > > (define-syntax O > (lambda (x) > (syntax-case x () > ((_) > #`(begin (use-modules (ice-9 local-eval)) > (local-eval 42 (the-environment))))))) > (pk (O)) This approach is misguided and unnecessary. You don't need to include 'use-modules' in your macro expansion, and it's best avoided. The references to 'local-eval' and 'the-environment' in the macro template above will refer to bindings present in the module where 'O' is defined, *not* the module where 'O' is used. This is part of what it means to say that 'O' is a "hygienic" macro. Therefore, all you need to do is make sure (ice-9 local-eval) is imported in the module where 'O' is defined, like this: --8<---------------cut here---------------start------------->8--- (define-module (my-module-that-exports-O) #:use-module (ice-9 local-eval) #:export (O)) (define-syntax O (lambda (x) (syntax-case x () ((_) #`(local-eval 42 (the-environment)))))) --8<---------------cut here---------------end--------------->8--- Does that work for you? FYI, the way this works internally is that the macro expander operates on "syntax objects" instead of plain S-expressions. The main difference is that "syntax objects" keep additional information about the lexical environments where the embedded identifiers were originally found. So when a use of (O) expands into (local-eval 42 (the-environment)), the identifiers 'local-eval' and 'the-environment' are looked up in the proper environment. By the way, another consequence of hygiene, which you probably don't want here, is that the (the-environment) above will capture the lexical environment where 'O' was *defined*, instead of the environment where (O) is used. In other words, in (let ((x 5)) (O)), the captured lexical environment will not include 'x'. I should also mention that using (the-environment) will pretty much disable most compiler optimizations that would otherwise occur with that top-level form. That entire mechanism is best avoided if at all possible. Can you tell me more broadly what you are trying to accomplish here? I may be able to suggest an alternate approach. Best, Mark