Reputation: 1921
(define x 44) (define y 25)
(let ((x 12) (y 23)) (if #f (eval x) (eval y)))
The above code returns 25, as eval uses global variables. How to create something similar to eval but looks for local variables when it sees variable references?
Upvotes: 0
Views: 262
Reputation: 13600
There is an other possible way to do it. I can't really do it for the moment but it can be done using an explicit environment.
If you look at the signature of eval
, you'll see that it accepts a third parameter.
http://wiki.call-cc.org/man/4/Unit%20eval#eval
[procedure] (eval EXP [ENVIRONMENT])
It might not be present on all scheme and even in chicken-scheme, this third parameter is almost useless at the moment.
What you could do is something like this.
(define x 25)
(define y 10)
(let* ((x 23)
(y 21)
(env (current-environment))
(print (eval '(x y) env)))
This sounds good in words but the current-environment
function is most likely to be the missing. I believe in gambit it is quite possible to do but even in chicken the environments module is deprecated and there is no alternative that I know of.
Upvotes: 1
Reputation: 33019
Not sure what Scheme you're using, but in Racket I get a different answer:
> (define x 44)
> (define y 25)
> (let ((x 12) (y 23)) (if #f (eval x) (eval y)))
23
This is the behavior I'd expect in any Scheme or Lisp. I think you meant to quote the x
and y
in eval
:
> (let ((x 12) (y 23)) (if #f (eval 'x) (eval 'y)))
25
Now we get the result you were expecting. If you don't quote the argument to eval
, then it gets evaluated and then passed in to eval
as a value instead of a form. In the previous case, you end up with (eval y)
--> (eval 23)
--> 23. However, you can take advantage of this using quasi-quoting, selectively unquoting variables that you want evaluated in the current scope:
> (let ((x 12) (y 23)) (eval `(if #f ,x ,y)))
23
Upvotes: 2
Reputation: 223003
Most Scheme implementations do not support references to lexical variables in their eval
. As a special case, Guile has local-eval
in its (ice-9 local-eval)
module, which does support lexical variables.
Upvotes: 2