[Top][All Lists]

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

Re: eval

From: Marius Vollmer
Subject: Re: eval
Date: 06 Feb 2001 20:49:39 +0100
User-agent: Gnus/5.0803 (Gnus v5.8.3) Emacs/20.7

Dirk Herrmann <address@hidden> writes:

> 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.

Yep.  You might also say that `(current-module)' determines the
environment that top-level code is executed in.  When the environment
is closed over to form a closure (this includes `let', etc), the
top-level environment for that closure is fixed and will not change to
another top-level environment.

(We need to fix `begin' to actually behave this way.  This is the
problem that Matthias is having.)

> So, the top level environment used by the evaluator may be distinct from
> (target-module) at any time.

Except when evaluating at the top-level.  There, `current-module' (or
target-module) is defined to return the environment that the code is
executed in.

> 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.

And so that the code that is evaluated at top-level can count on
target-module returning the top-level environment that the code is
executed in.  This guarantee is needed to make `export' and
`define-public' work, for example.

> 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.

Independent from whether the issue is evaluating and modules, I think
it is good practice to only change special global variables (fluids)
temporarily when they are needed for a specific task.  For example,
suppose we have (print-number N) that prints a number in base
`*base*', where *base* is a fluid variable, and we want to implement
(print-in-base N BASE) in terms of it.  Then the usual way is to do it
like this

    (define (print-in-base n base)
      (with-fluids ((*base* base))
        (print-number n)))

I view the situation with `eval' and `current-module' just like this
example.  It would simply be not good practice for `eval' to let
changes to `current-module' leak.  If the user wants that, he can use
`eval-in-current-module', which behaves differently.

>  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).

I think that this behaviour would be too hairy to specify, implement
and explain.  That's another reason why I proposed my simple solution:
it might not do what everybody wants it to, but it is easy to specify
and understand.

I will work on the stuff that I have proposed so far.  What does
everybody think of having a `eval-when' that can be used like this:

    (define-macro (export . syms)
          (module-export (current-module) ',syms))
          (error "export can only be used at top-level"))))

There would also be the situation `execute' for non-toplevel
occurrences, and `compile-toplevel' for a hypthetical compiler.

reply via email to

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