guile-devel
[Top][All Lists]
Advanced

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

eval


From: Dirk Herrmann
Subject: eval
Date: Thu, 1 Feb 2001 17:25:34 +0100 (MET)

Hello list-eners :-)

PROBLEM:
--------

Some time ago, the behaviour of eval in CVS was changed.  The effect of
that changes was, that after evaluating the given code, the environment
that was active before (eval ...) is restored.  In other words, code like
  (eval '(define-module (foo)) <environment>)
will not influence the (current-environment) after the evaluation is
finished.

The problem, however, is, that formerly it was possible to type
  (define-module (foo))
which was executed by the repl as
  (eval '(define-module (foo)) (interaction-environment))
and allowed to switch the current-environment to module foo.

Since this is not possible any more, there is no elegant way to switch to
a different environment in the repl.  A workaround is to type
  (begin (define-module (foo)) (scm-style-repl))
but this has the disadvantage that it starts a new repl.


SOLUTION:
---------

Instead of having only one global variable 'the-module', we have
'the-module' and 'the-interaction-module'.  Only 'the-module' is restored
after the execution of 'eval, while 'the-interaction-module' remains
changed after 'eval has finished.  The value of 'the-interaction-module'
is reported by (interaction-environment).


GENERALIZATION:
---------------

Imagine that we would like to guarantee that a call to 'load will neither
influence the current-module nor the interaction-module.  Still we want to
allow callers of 'load to determine which environment was active at the
end of the loading.

A generalization of the above concept is, instead of having a special
purpose variable the-interaction-module, we simply call it the-module*,
and don't couple it directly to (interaction-environment).  Instead, 
the repl would have to use the contents of the-module* after eval and use
that value to let (interaction-environment) report the new value:
  (begin (eval exp env) (set-interaction-environment! the-module*))
To realize the 'load' example above, the load function could be
implemented as
  (let loop ((env (current-module))
             (exp (read port)))
    (if (not (eof-object? exp))
        (begin
          (eval exp env)
          (loop the-module* (read port)))))
such that after 'load, the-module* would still hold the module that was
active at the end of load, but interaction-environment would not be
influenced.


Comments?


Best regards,
Dirk Herrmann







reply via email to

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