变量的作用域+ EVAL Clojure中 [英] Variable scope + eval in Clojure

查看:158
本文介绍了变量的作用域+ EVAL Clojure中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Clojure中,

 (DEF×3)
(EVAL(PRN X))

3打印的,而

 (让[Y 3]
   (EVAL(PRN Y)))

 (绑定[Z 3](EVAL'(PRN Z)))

生成一个无法解析变种的异常。

根据 http://clojure.org/evaluation 评估负载串等产生暂时的命名空间,以评估它们的内容。因此,我期望既不上述code样品的工作,因为(DEF×3)在我当前的命名空间是做,而不是一个接<创建code>评估。


  1. 为什么第一个code样品工作,而不是最后两个?

  2. 如何评估用绑定变量形式不使用 DEF

谢谢!


解决方案

1:

这不工作的原因是你的链接页面上给出(或多或少):

 如果没有用符号命名的全局变量这是一个错误[...]


  

[...]


  
  

      
  1. 一个查找在当前的命名空间做,看看是否有是一个映射
      从符号到一个变种。如果是,则
      值的结合的值
      VaR的简称,由符号。


  2.   
  3. 这是错误的。


  4.   

评估评估在一个空的形式(<一个href=\"http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/glo_n.html#null_lexical_environment\">null在CL-行话)词法环境。这意味着,你不能从呼叫者的范围内访问词法变量绑定。此外,结合创建现有瓦尔新的绑定,这就是为什么你不能用它本身,而无需声明 d或 DEF ED您尝试绑定的变量。此外,词法变量(至少在CL,但我会感到惊讶,如果这是不是Clojure的情况下)已经停止运行时存在 - 它们转化为地址或值

又见我的<一个href=\"http://stackoverflow.com/questions/2575262/executing-a-dynamically-bound-function-in-clojure/2575425#2575425\">older帖子这个话题。

2

所以,你必须使用动态变量。你可以避开明确的 DEF ,但你仍然至少需要声明它们(其中 DEF •不用绑定的VAR名称):

 用户=&GT; (x声明)
#用户/ X
用户=&GT; (装订[×10](EVAL(PRN x)的))
10

顺便说一句

:我想你知道为什么你需要的eval,那它的使用考虑邪恶当其他的解决方案将是合适的。

In Clojure,

(def x 3)
(eval '(prn x))

prints 3, whereas

(let [y 3]
   (eval '(prn y)))

and

(binding [z 3] (eval '(prn z)))

generate an 'Unable to resolve var' exception.

According to http://clojure.org/evaluation, eval, load-string, etc generate temporary namespaces to evaluate their contents. Therefore, I'd expect neither of the above code samples to work, since (def x 3) is done in my current namespace, not the one created by eval.

  1. Why does the first code sample work and not the last two?
  2. How can I eval a form with bound variables without using def?

Thanks!

解决方案

1.:

The reason this doesn't work is (more or less) given on the page you linked:

It is an error if there is no global var named by the symbol […]

And:

[…]

  1. A lookup is done in the current namespace to see if there is a mapping from the symbol to a var. If so, the value is the value of the binding of the var referred-to by the symbol.

  2. It is an error.

eval evaluates forms in an empty (null in CL-lingo) lexical environment. This means, that you cannot access lexical variable bindings from the caller's scope. Also, binding creates new bindings for existing vars, which is why you cannot use it "by itself", without having declared or defed the variables you try to bind. Besides, lexical variables (at least in CL, but I would be surprised if this wasn't the case for Clojure) already ceased to exist at runtime – They are translated to addresses or values.

See also my older post about this topic.

2.:

So, you have to use dynamic variables. You can avoid the explicit def, but you still at least need to declare them (which defs var names without bindings):

user=> (declare x)
#'user/x
user=> (binding [x 10] (eval '(prn x)))
10
nil

By the way: I suppose you know why you need eval, and that its use is considered evil when other solutions would be appropriate.

这篇关于变量的作用域+ EVAL Clojure中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆