Binding 可变范围+;在Clojure中评估
在ClojureBinding 可变范围+;在Clojure中评估,binding,clojure,eval,let,Binding,Clojure,Eval,Let,在Clojure (def x 3) (eval '(prn x)) 打印3份,而 (let [y 3] (eval '(prn y))) 及 生成“无法解析变量”异常 根据,eval,load string等生成临时名称空间以评估其内容。因此,我希望上述两个代码示例都不起作用,因为(def x 3)是在我当前的名称空间中完成的,而不是由eval创建的名称空间 为什么第一个代码示例有效,而最后两个不起作用 如果不使用def,如何eval带有绑定变量的表单 谢谢 1: 这不起作用的原因(
(def x 3)
(eval '(prn x))
打印3份,而
(let [y 3]
(eval '(prn y)))
及
生成“无法解析变量”异常
根据,eval
,load string
等生成临时名称空间以评估其内容。因此,我希望上述两个代码示例都不起作用,因为(def x 3)
是在我当前的名称空间中完成的,而不是由eval
创建的名称空间
def
,如何eval
带有绑定变量的表单It is an error if there is no global var named by the symbol […]
以及:
[……]
eval
在空(用CL术语)词汇环境中计算表单。这意味着您无法从调用者的作用域访问词法变量绑定。另外,binding
为现有变量创建新的绑定,这就是为什么在没有声明d或def
ed尝试绑定的变量的情况下,不能“单独”使用它的原因。此外,词汇变量(至少在CL中,但如果Clojure不是这样的话,我会感到惊讶)在运行时已经不存在了——它们被转换为地址或值
另请参见我关于此主题的介绍
2.:
所以,你必须使用动态变量。您可以避免显式的def
,但至少还需要声明它们(其中def
没有绑定的var名称):
顺便说一句:我想您知道为什么需要eval,它的使用是在其他解决方案合适的时候。请注意,这在Clojure 1.3中不起作用。您必须使用(declare^:dynamic x)
。谢谢!我现在明白我的问题了——我假设“null lexical scope”也指“null名称空间”,但快速测试表明eval
在当前名称空间中工作,这就是为什么它可以访问名称空间变量,但不能访问词法变量。回答得很好,你的链接也很有帮助!不客气!我很高兴这有帮助。另外,感谢您的接受。我想您应该引用内部(prnx)。我在尝试编写一个宏时遇到了这个问题,该宏将自动执行类似于(let[x41,y(incx)]{:xx,:yy})
(显然只对大型let块和大量复杂的数学感兴趣)。我尝试了(defmacro hashup[vars]`(apply hash map(map-vector(map-keyword~vars)(map-eval~vars)))
(只有一个backtick)并在这里遇到了问题。我看不出有什么办法可以使let块变干:(
It is an error if there is no global var named by the symbol […]
user=> (declare ^:dynamic x)
#'user/x
user=> (binding [x 10] (eval '(prn x)))
10
nil