List clojure尾部递归中的java.lang.StackOverflower错误

List clojure尾部递归中的java.lang.StackOverflower错误,list,loops,clojure,stack-overflow,reverse,List,Loops,Clojure,Stack Overflow,Reverse,我遇到以下代码的StackOverflower错误: (defn recursive-reverse ([coll] (recursive-reverse [coll nil])) ([coll acc] (if (= coll '()) acc (recur (rest coll) (cons (first coll) acc))))) 尽管使用loop可以让它工作: (defn recursive-reverse [lst] (loop [coll ls

我遇到以下代码的StackOverflower错误:

(defn recursive-reverse
  ([coll] (recursive-reverse [coll nil]))
  ([coll acc]
    (if (= coll '()) acc
        (recur (rest coll) (cons (first coll) acc)))))
尽管使用loop可以让它工作:

(defn recursive-reverse [lst]
  (loop [coll lst acc nil]
    (if (= coll '()) acc
        (recur (rest coll) (cons (first coll) acc)))))
以前没有循环的代码出了什么问题?

这对我很有用:

(defn recursive-reverse
  ([coll] (recursive-reverse coll nil))
  ([coll acc]
    (if (= coll '()) acc
        (recur (rest coll) (cons (first coll) acc)))))
您在几个不必要的括号内将参数传递给了递归反向,仅此而已。

您的错误如下:

([coll] (recursive-reverse [coll nil]))
您正在使用一个参数(向量)调用
递归反向
。这将调用函数的同一个参数列表,因此它递归地执行此操作,并每次创建一个堆栈帧

将其更改为:

([coll] (recursive-reverse coll nil))
你应该是对的

(还有一个单独的问题,但我通常会检查
nil
而不是
”()
,使用
next
而不是
rest
。我不认为它在性能或任何方面有任何真正的优势,但对我来说它似乎更干净。)

(nil?x)
可能比
(=x())
快得多,因为编译器只能发出一个字节码操作,所以Java使用的原语null检查。当然,后者相当快,但我怀疑它比前者慢好几倍。碰巧的是,这个优化的nil检查没有实现(还没有实现?),但它是一个合理的优化,最终可能会实现。