Clojure 编译器似乎会在编译函数调用时使用 vars 的 :arglists 元数据,方法与它们体内的函数递归调用与其动态指定的元数据冲突。
一个简单的例子
(defn foo
{:arglists (list '[n])}
[n]
(if (even? n)
n
(foo (dec n))))
会导致编译错误
语法错误(ClassCastException)在 REPL:6:5 编译 foo。类 clojure.lang.Symbol 无法转换为类 clojure.lang.IPersistentVector(clojure.lang.Symbol 和 clojure.lang.IPersistentVector 在名为 'app' 的未知模块中)
编译器似乎在解析对 foo
的调用时使用了未评估的 arglist 表达式 (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))