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

use*_*181 0 clojure

这有效:

(defn tri*
  ([] (tri* 0 1))
  ([sum n]
   (let [new-sum (+ sum n)]
     (cons new-sum (lazy-seq (tri* new-sum (+ n 1)))))))
Run Code Online (Sandbox Code Playgroud)

但当我使用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)))))))
Run Code Online (Sandbox Code Playgroud)

Mik*_*kes 6

lazy-seq是一个宏,它扩展为涉及零arg thunk的代码,可以在实现序列时调用.您可以看到recur表单被捕获为此thunk的主体

(macroexpand '(lazy-seq (recur new-sum (+ n 1))))
Run Code Online (Sandbox Code Playgroud)

要得到

(new clojure.lang.LazySeq (fn* [] (recur new-sum (+ n 1))))
Run Code Online (Sandbox Code Playgroud)

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

考虑所有这一切的另一种方式是,原始调用tri*早已完成(并且返回Cons包含LazySeqrest对象的对象)recur将被"评估".

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