2017-04-02 37 views
0

作爲將數據作爲數據操作的練習,我想取一塊Clojure代碼並更改所有bar調用foo調用。但是我在檢查函數平等方面遇到了一些困難。我的問題是:按名稱檢查Clojure函數的相等性

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

什麼是檢查第二個平等的正確方法?

回答

1

的原因是,你引用列表:

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

答案是,Clojure中的符號有特殊含義:他們自動進行變量替換。

如果您的原始問題已經使用的關鍵字或字符串,它會完美地工作:

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

(= "foo" (first '("foo")))) => true 
(= :foo (first '(:foo)))) => true 

請注意,我們需要引用列表,關閉「功能調用」它的默認含義。

同樣,符號有「變量替換」的缺省解釋:

(def doh 5) 
(= 5 doh) => true 

如果我們想要把符號doh爲一個數據,我們需要引用它來關閉默認行爲:

(= (symbol "doh") 'doh) => true 

注意:使用單引號遞歸引用報價單內的所有內容。這意味着我們可以關閉的「函數調用」括號和符號的只有一個單引號字符的「變量替換」行爲的行爲:

(=   'foo (first '(foo))) => true 
(= (symbol "foo") (first '(foo))) => true 

注意,symbol功能將轉換將常規文本字符串轉換爲符號。

最後,要注意的是,單引號字符只是在the Clojure Reader的「功能」命名quote快捷:

(= (quote foo) (first '(foo))) => true 

quote實際上是一個特殊形式,不是一個函數。這意味着它是內置於編譯器中的,並不遵循函數的正常規則。否則,它會自動進行變量替換和上面會看起來像:

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

注意(quote 5)5都具有相同的編譯器。由於整數5不等於包含符號foo的長度爲1的列表中的第一項,因此表達式爲false。