Debugging arity为(-1)的ArityException

Debugging arity为(-1)的ArityException,debugging,macros,clojure,Debugging,Macros,Clojure,有一个宏,我一直在试图找出这个错误,ArityException传递给用户/bar clojure.lang.Compiler.macroexpand1(Compiler.java:6557)的参数数目错误(-1)。我试图调试,但我不明白为什么在扩展宏时会出现一个(-1)的算术 我正在运行以下代码 (defn foo [x] (println x)) (defmacro bar [exp] (let [length (count exp)] (cond (= lengt

有一个宏,我一直在试图找出这个错误,
ArityException传递给用户/bar clojure.lang.Compiler.macroexpand1(Compiler.java:6557)
的参数数目错误(-1)。我试图调试,但我不明白为什么在扩展宏时会出现一个(-1)的算术

我正在运行以下代码

(defn foo [x] (println x))

(defmacro bar [exp]
  (let [length (count exp)]
    (cond
      (= length 0) '()
      (= length 1) exp
      :else (let [[head & tail] (vec exp)
                  [new-tail] (bar tail)]
        `(trap (~head ~@new-tail))))))

(macroexpand '(bar (inc 1)))

有人知道(-1)的算术是怎么回事吗?

使用REPL中的
*e
var打印堆栈跟踪

clojure.lang.ArityException: Wrong number of args (-1) passed to: user/bar
                                Compiler.java:6557 clojure.lang.Compiler.macroexpand1
                                     core.clj:3703 clojure.core/macroexpand-1
                                     core.clj:3712 clojure.core/macroexpand
这指向中的
clojure.lang.Compiler.macroexpand1
方法,我在其中找到了这一行:

throw new ArityException(e.actual - 2, e.name);
如果
e.actual
1
,则对于
ArityException
构造函数的第一个参数,结果为
-1
。有一张JIRA罚单提到了这条非常混乱的
ArityException
消息

根据这张票上的内容,我开始在其他地方寻找一个
ArityException
,并在使用
count
vec
时发现它,就好像
exp
总是一个列表一样

问题是,当递归调用宏
bar
时,参数实际上是符号
尾部
,它不是一个集合,当调用宏时创建宏本身时,此调用实际上是宏扩展的

更改宏的代码,使其考虑非列表的可能值,可以解决问题,尽管我认为生成的宏不能满足您的要求

(defmacro bar' [exp]
  (prn exp)
  (let [length (if (seq? exp) (count exp) 0)]
    (cond
      (= length 0) '()
      (= length 1) exp
      :else 
      (let [[head & tail] (if (seq? exp) (vec exp) [exp])
            [new-tail] (bar' tail)]
        `(trap (~head ~@new-tail))))))
;; tail

(macroexpand '(bar' (inc 1)))
;; (inc 1)
;;= (user/trap (inc))

我完全忘了检查
*e
,我是Clojure的新手。但是谢谢你的链接并提到
*e
var,你的帖子帮了忙@我发现了问题所在。请检查上面的答案。谢谢你找到答案和解释!这很有帮助。