Clojure编译器在编译函数调用时似乎使用了vars的:arglists元数据,这在与动态指定元数据的形式体中递归调用的函数冲突时会出现。
一个简单示例
(defn foo
{:arglists (list '[n])}
[n]
(if (even? n)
n
(foo (dec n))))
导致编译错误
语法错误(ClassCastException)在编译foo时于(REPL:6:5)抛出。无法将类clojure.lang.Symbol转换为类clojure.lang.IPersistentVector(clojure.lang.Symbol和clojure.lang.IPersistentVector在由loader 'app'组成的未命名模块中)
在解析对foo的调用时,编译器似乎使用了未评估的参数列表形式(list (quote [n]))
,由于符号list
不是期望的参数向量,因此抛出了异常。
这里有一个更接近现实的例子,这种情况可能发生
(def ^:private shape-attrs
'{:keys [height width color]})
(defn draw
{:arglists (list ['shape]
['shape shape-attrs])}
([shape]
(draw shape {:color "black"}))
([shape attrs]
:ok))