按名称检查Clojure函数的相等性

按名称检查Clojure函数的相等性,clojure,lisp,Clojure,Lisp,作为将代码作为数据进行操作的练习,我想获取一段Clojure代码,并将所有bar调用更改为foo调用。但我在检查函数相等性时遇到了一场斗争。我的问题是: (= foo foo) ;returns true (= foo (first `(foo))) ;returns false 检查第二个等式的正确方法是什么?原因是您引用了以下列表: > (= 'foo (first '(foo))) true > (= 'foo (first (list foo))) false >

作为将代码作为数据进行操作的练习,我想获取一段Clojure代码,并将所有
bar
调用更改为
foo
调用。但我在检查函数相等性时遇到了一场斗争。我的问题是:

(= foo foo) ;returns true
(= foo (first `(foo))) ;returns false 

检查第二个等式的正确方法是什么?

原因是您引用了以下列表:

> (= 'foo (first '(foo)))
true
> (= 'foo (first (list foo)))
false
> (= foo (first (list foo)))
true

答案是clojure中的符号是特殊的:它们自动执行变量替换

如果您最初的问题使用了关键字或字符串,那么它将非常有效:

(= "foo" (first ["foo"])))     => true
(= :foo  (first [:foo ])))     => true

(= "foo" (first '("foo") )))   => true
(= :foo  (first '(:foo ) )))   => true
请注意,我们需要引用该列表以关闭其默认含义“函数调用”

类似地,符号具有“变量替换”的默认解释:

如果我们想将符号
doh
视为一段数据,我们需要引用它以关闭默认行为:

(= (symbol "doh") 'doh)   => true
注意:使用单引号递归地引用引用表单中的所有内容。这意味着我们可以关闭括号的“函数调用”行为和仅使用一个引号字符的符号的“变量替换”行为:

(=         'foo    (first '(foo)))   => true
(= (symbol "foo")  (first '(foo)))   => true
请注意,
symbol
函数将常规文本字符串转换为符号

最后,请注意,单引号字符只是名为
quote
的“函数”的快捷方式:

(= (quote foo)  (first '(foo)))   => true
quote
实际上是一种特殊形式,而不是函数。这意味着它内置在编译器中,不遵循函数的正常规则。否则,它会自动执行变量替换,上面的内容如下:

(= (quote 5) (first '(foo)))   => false
请注意
(引号5)
5
对于编译器都是相同的。由于整数
5
不等于包含符号
foo
的length-1列表的第一项,因此表达式为false

(= (quote 5) (first '(foo)))   => false