像这样:
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)
第一次定义时,(meta f)
包含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=>
答案 0 :(得分:1)
显然,这种行为在Clojure 1.2中或多或少是“偶然的”,并且在1.3中已经改变: http://groups.google.com/group/clojure/browse_thread/thread/964bba0ead8218ee/3ef0c841474c85f4?lnk=gst&q=function+meta+data#3ef0c841474c85f4
在1.3中,只有Var包含元数据 - 函数本身未按defn
分配任何元数据。
答案 1 :(得分:0)
Clojure使用元数据来存储从中读取函数的信息,文档等。重新定义函数可以改变它。
来自http://clojure.org/metadata:
理解元数据的一个重要事项是它不被视为对象价值的一部分。因此,元数据不会影响相等(或哈希码)。仅在元数据方面不同的两个对象是相同的。
另一种看待这种情况的方法是考虑相反的情况:假设Clojure没有重置元数据。
(defn fun []
"docs for the original function"
...)
然后重新定义它:
(defn fun []
;; no doc string, different body
...)
如果不重置元数据(doc fun)
,则会显示“原始函数的文档”。
最后,vars的重新定义通常在开发期间完成,通常不在程序的正常执行中。因此,完全重新定义它而不是保留以前定义中的内容是有意义的。