From: Mark H Weaver <mhw@netris.org>
To: David Kastrup <dak@gnu.org>
Cc: guile-devel@gnu.org
Subject: Re: A plea for local-eval in 2.0.4
Date: Fri, 13 Jan 2012 20:07:47 -0500 [thread overview]
Message-ID: <87pqen6qho.fsf@netris.org> (raw)
In-Reply-To: <87boq777xz.fsf@fencepost.gnu.org> (David Kastrup's message of "Fri, 13 Jan 2012 19:50:48 +0100")
Probably the easiest way to think about it is that (the-environment)
acts like (list (lambda () <expr>) ...), with one `lambda' for each
expression that you will later pass to `local-eval'. Calling
`local-eval' simply calls the appropriate procedure in that list.
Of course, it can't actually work that way, but that's an easy way to
think about it. You could also imagine that it builds an infinite list,
one for each possible expression.
Calling the procedure created by a lambda expression evaluates the
lambda body within the _lexical_ environment of the lambda expression,
but within the _dynamic_ environment of the procedure call. Top-level
variables are part of the _lexical_ environment. That means that
top-level variable references within a procedure are looked up in the
module where the procedure was defined, _not_ the (current-module) at
the time of the procedure call.
Similarly, calling `local-eval' evaluates the expression within the
lexical environment of (the-environment), but within the _dynamic_
environment of the call to `local-eval'.
The dynamic environment conceptually includes the current continuation,
the set of fluid/parameter bindings currently in effect, and also
determines the associated dynamic extent for purposes of dynamic-wind,
catch/throw, etc.
The lexical environment includes bindings for lexical and top-level
module variables, syntactic keywords, pattern variables, etc.
David Kastrup <dak@gnu.org> writes:
> Mark H Weaver <mhw@netris.org> writes:
>
>> David Kastrup <dak@gnu.org> writes:
>>> I am still fuzzy on what local-eval will do when the current module at
>>> the time of the-environment is different from that at the time of
>>> local-eval.
>>
>> (the-environment) saves the module (where it is textually located) in
>
> What does "where it is textually located" mean?
This simple description covers the common case where a module is defined
in its own source file with `define-module' at the top. (I covered
other cases in subsequent sentences). It means the module that actually
contains the string "(the-environment)". For example, suppose you
define the following macro in module (A):
(define-syntax-rule (foo)
(let ((x 1) (y 2))
(the-environment)))
and then in module (B) you evaluate:
(let ((x 111) (y 222))
(foo))
The captured lexical environment includes the bindings for `x' and `y'
from the macro definition of (foo), i.e. the variables that are
initially set to 1 and 2, and it also includes a reference to module
(A), because modules are conceptually part of the lexical environment.
Why? Because if you replaced (the-environment) with (list x y z), the
reference to `z' would refer to the binding of `z' in the module where
(foo) was defined, namely module (A). It's as simple as that.
>> I heartily disagree. A module is conceptually part of every lexical
>> environment evaluated within that module.
>
> What does "evaluated within a module" mean?
I used sloppy wording there. Let me try again.
Forms passed to `eval' are part of the module specified by `eval's
second parameter.
Forms passed to `primitive-eval' are part of the module returned by
(current-module) at the time when `primitive-eval' was called.
Within a compiled file, it is possible to change the module part way
through the file, using either `define-module' or something like this:
(eval-when (compile)
(set-current-module (resolve-module '(foo bar))))
and in this case, top-level forms after this `eval-when' are part of the
(foo bar) module.
The key point is, every top-level form belongs to a single module. The
module is baked into the top-level form at macro expansion time, and
cannot later be changed. It is this _fixed_ compile-time module where
top-level variable references are looked up, and therefore this is the
module captured by (the-environment).
Mark
next prev parent reply other threads:[~2012-01-14 1:07 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-12 21:43 A plea for local-eval in 2.0.4 Mark H Weaver
2012-01-12 23:02 ` Bruce Korb
2012-01-13 9:20 ` David Kastrup
2012-01-13 16:21 ` Mark H Weaver
2012-01-13 18:50 ` David Kastrup
2012-01-14 1:07 ` Mark H Weaver [this message]
2012-01-14 8:59 ` David Kastrup
2012-01-14 15:04 ` Andy Wingo
2012-01-14 15:16 ` David Kastrup
2012-01-14 15:33 ` Andy Wingo
2012-01-14 16:17 ` Mark H Weaver
2012-01-14 17:20 ` David Kastrup
2012-01-14 17:59 ` Mark H Weaver
2012-01-14 18:04 ` David Kastrup
2012-01-14 18:35 ` David Kastrup
2012-01-14 19:04 ` Mark H Weaver
2012-01-14 15:24 ` Andy Wingo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pqen6qho.fsf@netris.org \
--to=mhw@netris.org \
--cc=dak@gnu.org \
--cc=guile-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).