Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 函数符号与局部变量_Clojure - Fatal编程技术网

Clojure 函数符号与局部变量

Clojure 函数符号与局部变量,clojure,Clojure,下面的代码按预期打印10 (def x 10) (let [y 30] (eval (symbol "x"))) 下面的代码生成一个异常: (let [y 20] (eval (symbol "y"))) Unable to resolve symbol: y in this context 这是意料之中的(但令人困惑!)。根据文档,let定义的符号不属于任何名称空间,因此无法通过名称空间机制进行解析 所以问题是:对于局部变量,什么应该是函数符号的等价物 此外: 我认为Clojure编译

下面的代码按预期打印10

(def x 10)
(let [y 30] (eval (symbol "x")))
下面的代码生成一个异常:

 (let [y 20] (eval (symbol "y")))
 Unable to resolve symbol: y in this context
这是意料之中的(但令人困惑!)。根据文档,let定义的符号不属于任何名称空间,因此无法通过名称空间机制进行解析

所以问题是:对于局部变量,什么应该是函数符号的等价物

此外:

我认为Clojure编译器在内部调用每个标识符的函数符号来“插入”它,但正如上面的示例所示,情况并非如此。我很好奇编译器到底在用本地标识符做什么。我假设当我在REPL中输入x时

 x
基本上是这样处理的:

 (deref (resolve (symbol "x")))
但显然,局部变量的情况并非如此


PS:不包括局部变量。

读取clojure编译器的所有输入,以形成列表、符号、关键字、数字和其他可读数据(例如,如果使用哈希映射文字,编译器将获得哈希映射)

例如:

user=> (eval '(let [y 20] y))
20
在本例中,我们给编译器一个以符号
let
开头的列表(它解析为一个包装特殊形式的var宏)

当你问“对于局部变量,什么应该是函数符号的等价物”时,我的第一个想法是你误解了函数
symbol
的用途。以下内容相当于我的初始示例:

user=> (eval (list (symbol "let") [(symbol "y") 20] (symbol "y")))
20

symbol
仅在从字符串获取变量时顺便有用。事实上,这种用法通常是一种恶作剧,表明你做错了什么。它的主要目的是为编译器构造输入。编写从词法范围获取绑定的表单最好通过编写函数并让用户传入要使用的值来完成。历史告诉我们,在调用者环境中隐式使用局部变量既麻烦又容易出错,而且Clojure也不明确支持这一特性(尽管肯定会有一些黑客攻击,这些攻击将基于实现细节,但不能保证在下一版本的语言中正常运行)。

谢谢。没有计划编写这样的代码。只是想理解Clojure:(eval(list'let['y 20]'y))