guile-devel
[Top][All Lists]
Advanced

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

Re: eval


From: Dirk Herrmann
Subject: Re: eval
Date: Mon, 5 Feb 2001 15:14:04 +0100 (MET)

On 5 Feb 2001, Marius Vollmer wrote:

> No, I don't think I made myself clear enough.  What I propose is a
> _very_ simple thing.

Ah!  I think I got it now :-)  Let me try to state your idea from a
different point of view:

The notion of a (current-module) is an orthogonal concept to the question,
what is the top level environment of the currently executed code.  This
goes along with the way the evaluator works.  The evaluator does _not_
look into the contents of (current-module) at all.  Instead, the
environment that is used for lookup is a list of local-environments plus a
top-level environment as the last list element.  Taking this into account,
the semantics of (current-module) is:  "New bindings will be created in
this module".  In contrast, there is currently no way to actually get the
evaluator's current top level environment.

Right?  (Assuming that this is right, I will in the following use the term
target-module instead of current-module in order to avoid confusion:  
>From the term current-module I somehow expect that it will return the top
level environment used by the evaluator...)

So, the top level environment used by the evaluator may be distinct from
(target-module) at any time.  In this sense, (target-module) is comparable
to (interaction-environment), since both return environments that
correspond to global variables that can in principle be changed at
arbitrary moments, without influencing the top level environment that is
currently used by the evaluator.

The need to sync (target-module) and the evaluators top level environment
when doing 'eval comes from the requirement, that definitions made during
'eval appear in the environment given to eval.  This is the way that R5RS
defines eval to work.

  BTW: This gives a nice idea, btw:  According to R5RS, the report
  environment and the null environment should be treated as
  read-only.  One could implement this request in the following way:  If
  the environment passed to eval is one of these, eval does not set the
  target-module to it, but either to something stupid, like #f, or to some
  empty environment that is used as a nirvana.   (I don't think that this
  is the best way to implement read-only environments:  It is just an
  example to demonstrate that there is actually conceptual orthogonality
  between the current evaluation environment and the concept of the
  target-module.)

The decision to restore (target-module) after evaluating is somewhat
arbitrary.  I only changed it that way, because I had the misconception
that (current-module) should return the top level environment of closures
as well (it is now clear to me that it never really worked that way :-).

> Then, we need to provide a R5RS compliant version of `eval' that does
> the Right Thing in the presence of modules.  The right thing is to set
> the current module to its second argument while evaluating its first
> argument, but shielding the rest of the system from this temporal
> change of the current module.

Hmmm.  I have thought about this again, and I wonder if it is really the
best choice to _always_ restore the target-module after evaluation.  It
would probably really be the best choice if:

  (eval '(+ 1 2) some-module)

would restore the target-module, but

  (eval '(define-module (foo)) some-module)

would switch target-module to (foo).  The problem that I had with this was
the question:  How can we detect that target-module was actively changed
by the code and distinguish that change from the implicit change done at
the beginning of eval?  But, I have a simple solution for this idea now:  
target-module is implemented using a pair (module . changed?).  If
target-module is changed, the boolean value is set to #t.  This is used by
eval:  Before eval starts to evaluate the expression, it sets the
target-module to the given environment and sets changed? to #f.  After
eval has executed its expression, it switches the target-module back only
if it was not explicitly changed.  Otherwise, eval does not switch back to
the original target-module and sets changed to #t, to indicate that
target-module was changed by the evaluated expression.

Now to the question how (interactive-environment) relates to
(target-environment):  The repl would simply work like follows:

  ...
  <set changed? flag to #f>
  (eval exp (interaction-environment))
  (if <changed? flag is #t>
    (set-interaction-environment! (target-module)))
  ...

That is, only if the target-module is explicitly changed in an interactive
session, this will effect the (interaction-environment).

> > that it is somewhat clumsy to modify some glocal variable as a
>                                             ^^^^^^
> What is this?  Interesting word, indeed... :-)

Oops :-)  Yes, that's a nice one, especially since it was completely
unintended:  I meant global here.

Best regards,
Dirk Herrmann




reply via email to

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