将列表评估为let on clojure

时间:2011-12-28 23:35:06

标签: binding clojure eval let

我的问题是下一个,我尝试使用let to toign值来评估一个包含一些变量的列表

如果我(def a (list * 'x 'y))(let [x 3 y 3] (eval a))我有 CompilerException java.lang.RuntimeException:无法在此上下文中解析符号:x,编译:(NO_SOURCE_PATH:6)

但如果我跑了 (def x 4) (def y 4)(eval a)我有一个16,无论如何,如果我再次跑(let [x 3 y 3] (eval a)),我有16,

是否存在正确绑定x和y并对列表进行评估的方法?

TY!

3 个答案:

答案 0 :(得分:5)

let定义了无法从eval函数体中访问的词法范围绑定。这与任何其他功能没有什么不同。但是,使用def创建的绑定是可访问的,因为它们是名称空间全局的。所有函数都可以访问命名空间全局变量,只要它们是公共的。

答案 1 :(得分:3)

(def ^:dynamic x 4) (def ^:dynamic y 4)
user=> (binding [x 3 y 3] (eval a))
9
user=> (eval a)
16

答案 2 :(得分:2)

好吧,您也可以eval let表达式,看看这是否是您需要的:

(eval '(let [x 3 y 3] (* x y)))

编辑:

根据评论,这适用于您的情况:

(def a (list (list * 'x 'y)))
(eval (concat '(let [x 3 y 3]) a))

更好的是,使用quasiquoting:

(def a (list * 'x 'y))
(eval `(let ~'[x 3 y 3] ~a))