eval with local bindings

204 views
Skip to first unread message

Nathan Kitchen

unread,
Dec 17, 2007, 3:17:18 PM12/17/07
to Clojure
I noticed that eval only uses var bindings, not lexical bindings. For
example:

user=> (def expr '(+ x 4))
#<Var: user/expr>
user=> (let [x 3] (eval expr))
clojure.lang.Compiler$CompilerException: REPL:3: Unable to resolve
symbol: x in this context
at clojure.lang.Compiler.analyzeSeq(Unknown Source)
at clojure.lang.Compiler.analyze(Unknown Source)
at clojure.lang.Compiler.analyze(Unknown Source)
at clojure.lang.Compiler.eval(Unknown Source)
at clojure.eval.invoke(boot.clj:619)
[...]
user=> (def x)
#<Var: user/x>
user=> (binding [x 3] (eval expr))
7

I would like to write some code that does heavy manipulation of
expressions, and I think it would be cleaner to have a version of eval
that doesn't require global variables to be defined.

John Cowan

unread,
Dec 17, 2007, 3:52:23 PM12/17/07
to clo...@googlegroups.com
On Dec 17, 2007 3:17 PM, Nathan Kitchen <nathan....@gmail.com> wrote:

> I noticed that eval only uses var bindings, not lexical bindings. For
> example:

That's the same behavior used by eval on all modern (i.e. lexically
scoped) Lisps like CL and Scheme. The whole point of *lexical* scoping
is that the binding is only in effect in the part of the code physically
between "(let" and ")" -- or lambda, or let*, or whatever. So in
your example:

> user=> (def expr '(+ x 4))
> #<Var: user/expr>
> user=> (let [x 3] (eval expr))

there's no way that the binding of x to 3 can be available
to eval, because the expression to be evaluated is not within
the scope of the let. Consequently, all variable references
in code evaluated by eval are global.

It wouldn't help to say (eval '(+ x 4)), because a symbol that is
referenced in a quoted constant is still not within the scope
of any lexical binding introduced by let -- it's just a piece
of list structure, not actually a piece of code.

--
GMail doesn't have rotating .sigs, but you can see mine at
http://www.ccil.org/~cowan/signatures

Reply all
Reply to author
Forward
0 new messages