何时使用纯递归以及何时使用循环/重复?

Yur*_*rev 8 recursion clojure

"纯粹的递归"是一个虚构的术语,请原谅.

以下是使用两种不同递归方法的两个示例.一个用户的使用指南是什么?

(defn take-while
  "Returns a lazy sequence of successive items from coll while
  (pred item) returns true. pred must be free of side-effects."
  {:added "1.0"
   :static true}
  [pred coll]
  (lazy-seq
   (when-let [s (seq coll)]
       (when (pred (first s))
         (cons (first s) (take-while pred (rest s)))))))

(defn take-last
  "Returns a seq of the last n items in coll.  Depending on the type
  of coll may be no better than linear time.  For vectors, see also subvec."
  {:added "1.1"
   :static true}
  [n coll]
  (loop [s (seq coll), lead (seq (drop n coll))]
    (if lead
      (recur (next s) (next lead))
      s)))
Run Code Online (Sandbox Code Playgroud)

mik*_*era 9

需要考虑的几个因素:

  • loop/recur不占用堆栈空间 - 所以如果你要进行深层嵌套递归,那么它是正确的选择,否则会导致StackOverflowError
  • loop/recur更快 - 它是Clojure中最有效的结构之一,正确完成它应该匹配Java代码中等效for循环的速度
  • 正常递归更惯用 - 平均而言,它往往会为您提供更清晰,功能更强大的代码,而循环/重复则往往会让您更加注重命令式,迭代式
  • loop/recur有更多的限制 - 你只能在尾部位置重复,你不能在两个不同的函数之间进行相互递归,等等.有时它根本不可能使循环/重复工作,在其他时候你可能需要扭曲你的代码来做到这一点.