不能在多元Clojure函数中使用recur

时间:2018-01-20 13:13:02

标签: clojure

这有效:

(defn tri*
  ([] (tri* 0 1))
  ([sum n]
   (let [new-sum (+ sum n)]
     (cons new-sum (lazy-seq (tri* new-sum (+ n 1)))))))

但当我在其中使用recur时,我会得到CompilerException

  

不匹配的参数计数重复,预期0参数,得到:2

(defn tri*
  ([] (tri* 0 1))
  ([sum n]
   (let [new-sum (+ sum n)]
     (cons new-sum (lazy-seq (recur new-sum (+ n 1)))))))

1 个答案:

答案 0 :(得分:6)

lazy-seq是一个宏,它扩展为涉及零arg thunk的代码,可以在实现序列时调用。您可以通过执行

看到recur表单被捕获为此thunk的主体
(macroexpand '(lazy-seq (recur new-sum (+ n 1))))

获取

(new clojure.lang.LazySeq (fn* [] (recur new-sum (+ n 1))))

表明recur的目标是thunk,而不是tri*

考虑所有这一切的另一种方式是,tri*的原始调用早已完成(并且在Cons时返回包含LazySeq rest对象的recur对象1}}将被“评估”。

您的tri*的第一个版本很好,因为对tri*的递归调用不会增加堆栈,而只是创建一组新的Cons / {{ 1}}对象。