“纯递归”是一个虚构的术语,请原谅。
以下是使用两种不同递归方法的两个示例。使用一个在另一个上的指导原则是什么?
(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)))
答案 0 :(得分:9)
需要考虑的几个因素:
StackOverflowError
答案 1 :(得分:2)
使用lazy-seq
/ lazy-cons
机制的唯一原因是生成延迟序列。如果您不需要它们,那么毫无疑问会使用loop
/ recur
。
答案 2 :(得分:1)
首先编写函数时使用普通递归。如果可以的话,一旦你完成所有工作,然后将其更改为重复。
TCO的一个问题是,如果你不推测你的递归,你会得到一个无限的外观。没有,你的代码很好地崩溃堆栈溢出,这是你想要的。当我第一次听到它时,我不喜欢复发的想法 - 大多数优化都应该发生 - 但能够将其关闭是很好的。