2017-01-19 41 views
0

在O'Reilly的 「Clojure的編程:實用Lisp語言在Java世界」,有一種說法:如果x在clojure中評估爲(var x),爲什麼它們不相等?

var這個特殊形式做到這一點:

(def x 5) 
(var x) 
;= #' user/x 

你」現在已經多次看到如何在REPL中打印變量:#',後面跟着一個符號。這是讀者語法擴展到調用VAR:

#'x 
;= #' user/x 

(Kindle的位置1278至1282年)。

測試結果似乎並非如此。我會認爲類型類型是相同的。

[user]> (def x 5) 
#'user/x 

[user]> (= 'x (var x)) 
false 

[user]> (type 'x) 
#<[email protected] clojure.lang.Symbol> 

[user]> (type (var x)) 
#<[email protected] clojure.lang.Var> 

[user]> 'x 
x 

[user]> (var x) 
#'user/x 
+0

''x'評估爲'(quote x) ',而不是'(var x)'。 '(='x(quote x))'評估爲'true'。 'x'只是一個符號。它不需要引用'var'或其他任何東西。 – Thumbnail

回答

5

你缺少#符號:

(def x 5) 
(spyx (var x)) 
(spyx #'x) 

(var x) => #'tst.clj.core/x 
(var x) => #'tst.clj.core/x 

Clojure的讀者消耗charcters在源文件中,並執行的#'x =>(var x)替代之前,甚至會到編譯器。如上所見,spyx宏(「間諜表達式」)甚至不會看到原始#'x表達式 - 已經發生了替換。

因此,我們得到:

(= #'x (var x)) => true 

你還可以嘗試:

(println "type 1: " (type (var x))) 
(println "type 2: " (type #'x)) 

;=> type 1: clojure.lang.Var 
;=> type 2: clojure.lang.Var 

如果你想與spyspyx,或spyxx宏玩,你將需要添加到您的project.clj

[tupelo "0.9.19"] 
+0

通過檢查簡單引用輸入的結果,可以更清楚地顯示讀取時間替換:'[(var x)#'x]'。 – amalloy

+0

啊,謝謝。你知道,我想我很困惑,並認爲'#'是一個提示。 – marathon

相關問題