Andreas Steffan
Andreas Steffan

Reputation: 6169

Why can symbol in eval not be resolved?

Why does

((fn[x] (eval (symbol "x"))) 1)

blow up Unable to resolve symbol: x in this context?

I expected it to behave just like

((fn[x] x) 1)  

and evaluate to 1.

(How) Can the former be fixed to return 1 using eval?

Upvotes: 1

Views: 111

Answers (1)

noisesmith
noisesmith

Reputation: 20194

eval does not use the lexical scope where it is called (as introduced by fn, let, or loop), it only sees vars as mapped via the current namespace (bound to the var *ns*).

Introducing a lexical binding into an eval context will involve wrapping the form in a let manually, or using undocumented implementation dependent host interop to find and provide lexical bindings to the eval context.

An example of wrapping in a let manually (this will only work when x is something readable by the Clojure reader):

user=> (def x 0)
#'user/x
user=> (let [x 42] (eval 'x)) ; gets the global value of x, not local
0
user=> (let [x 42] (eval (list 'let ['x (list 'quote x)] 'x))) ; manually getting the local
42

Upvotes: 2

Related Questions