Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!usc!rutgers!mcnc!rock.concert.net!jazz!hayes From: hayes@jazz.concert.net (Brian Hayes - Sigma Xi) Newsgroups: comp.lang.scheme Subject: Re: EVAL in Scheme Message-ID: <1991Mar5.160735.24566@rock.concert.net> Date: 5 Mar 91 16:07:35 GMT References: <13781@asylum.SF.CA.US> Sender: news@rock.concert.net Organization: Center for Communications, MCNC; RTP, NC Lines: 69 In Article 268 in comp.lang.scheme Marc Feeley (feeley@chaos.cs.brandeis.edu) writes: > However, it is not possible to write a portable EVAL procedure because there > is no way in standard Scheme (R4RS or IEEE) to access global variables > through their names. We would like the following code to print 100: > (define x 50) > (EVAL '(set! x (+ x x))) > (write x) > EVAL would be possible given procedures to reference and set global variables > (and perhaps define them), for example (global-var-ref name) and > (global-var-set! name val). Think of global-var-ref as: > (define (global-var-ref name) > (case name > ((a) a) > ((b) b) > ... etc for all possible variable names! > and similarly for global-var-set!. Feeley's example seems to suggest there is something uniquely weird about the global environment. But if I understand what's going on here--and admittedly my confidence is not terribly high on that point--the same problem would arise with an attempt to access a variable in *any* lexically enclosing environment. For example, (let ((z 50)) (begin (EVAL '(set! z (+ z z))) (write z))) ought to cause the same trouble. We can teach our EVAL how to bind variables that are created within its own scope, but it doesn't know where to look for the values of variables anywhere outside that scope. Doesn't this line of reasoning lead to the conclusion that EVAL is inextricably part of the interpreter, rather than something we can add on to an existing interpreter? EVAL has to know how environments are represented internally. Hence it seems the only way to write EVAL within Scheme is to write an entire Scheme within Scheme. Facilities for finding global variables--but not local variables introduced in enclosing scopes--would not be enough. As it happens, in at least some implementations of Scheme, the global environment is the only enclosing scope where EVAL *can* find variables. For instance, when I run Feeley's sequence of expressions through MacScheme or through TI's PC Scheme--using the versions of EVAL supplied in those interpreters--the result is the expected (correct?) one: the interpreter writes "100". But both MacScheme and PC Scheme choke on the example with the (let ...) expression, complaining of an undefined variable z. The reason is that both EVALs choose, unless told otherwise, to evaluate an expression in the global, top-level environment. They can find x there, but the let- bound z is invisible from the top-level vantage. Incidentally, I tried this experiment in one more version of Scheme: Pixie Scheme, an interpreter available for a fee of $1.00 from Jay Reynolds Freeman. Pixie Scheme also complains of an unbound variable, but the variable is not x or z; it is EVAL. No environmental ambiguities in Pixie Scheme. Brian Hayes hayes@concert.net