像這樣:Clojure:當我重新輸入它的定義時,爲什麼函數的元數據會改變?
java -cp clojure.jar clojure.main
Clojure 1.2.0
user=> (defn f [x] x)
#'user/f
user=> (meta f)
{:ns #<Namespace user>, :name f}
user=> (defn f [x] x)
#'user/f
user=> (meta f)
{:ns #<Namespace user>, :name f, :file "NO_SOURCE_PATH", :line 1, :arglists ([x])}
user=>
爲什麼不調用meta
返回每次都相同的值?
更新:通過玩更多我能夠得到我的直接問題的答案。 defn
宏擴展爲將(meta (var f)
添加到f
的元數據的表單。並且(meta (var f)
包含第一次定義f
時不在(meta f)
中的額外信息。所以我的問題現在變成了,爲什麼defn
這樣實現?
java -cp clojure.jar clojure.main
Clojure 1.2.0
user=> (defn f [x] x)
#'user/f
user=> (meta f)
{:ns #<Namespace user>, :name f}
user=> (meta (var f))
{:ns #<Namespace user>, :name f, :file "NO_SOURCE_PATH", :line 1, :arglists ([x])}
user=> (macroexpand '(defn f [x] x))
(def f (.withMeta (clojure.core/fn f ([x] x)) (.meta (var f)))) ; (.meta x) seems to be the same as (meta x)
user=>
但我沒有重新定義函數,我只是第二次輸入相同的定義(並且讀取函數的位置也是相同的,即REPL)。根據固定表達式應該有一個常數值並應儘可能避免副作用的原則,看起來很奇怪的是,重複'defn'這樣的簡單操作可以爲元數據添加新的信息,這些信息可能已經第一次添加(我明白這不會影響表達的價值,但它仍然感覺不對)。 – OpenSauce
即使函數相同,再次定義函數也是重新定義的。 Clojure不記得你的定義,只記得編譯好的代碼,它並不試圖比較舊的和新的。 – ivant
好點,+1。但是,我發佈了來自Google小組的帖子,並接受了這個帖子,因爲它更接近我正在尋找的內容。 – OpenSauce