Reputation: 6169
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
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