guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Implement `the-environment' and `local-eval' in evaluator


From: Mark H Weaver
Subject: Re: [PATCH] Implement `the-environment' and `local-eval' in evaluator
Date: Fri, 16 Dec 2011 12:44:30 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

Andy Wingo <address@hidden> 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]