1. 直接转化为自递归
不是那么容易
2. Trampolining
(trampolining f & partial-args)
如果f的返回值不是一个函数,那么trampoline就像直接调用了f一样;
如果f的返回值是一个函数,那么trampoline会假定你打算递归的调用这个函数,并替你执行该调用。trampoline管理着它自己的recur,所以它会一直调用你的函数,知道返回的不再是函数为止。
(declare my-odd? my-even?)
(defn my-odd?
[n]
(if (zero? n)
false
#(my-even? (dec n))))
(defn my-even?
[n]
(if (zero? n)
true
#(my-odd? (dec n))))
(println (trampoline my-even? 1000000))
3.用惰性化代替递归(lazy)
(defn lazy-parity
[]
(iterate (partial - 1) 0))
(defn my-even2?
[n]
(= 0 (nth (lazy-parity) n)))
(defn my-odd2?
[n]
(false? (my-even2? n)))
(println (my-even2? 1000000))
replace的例子(这里用到了clojure的另外一个特性multi-method):
(defn- coll-or-scalar [x & _] (if (coll? x) :collection :scalar))
(defmulti replace-symbol coll-or-scalar)
(defmethod replace-symbol :collection
[coll oldsym newsym]
(lazy-seq
(when (seq coll)
(cons (replace-symbol (first coll) oldsym newsym)
(replace-symbol (rest coll) oldsym newsym))))
)
(defmethod replace-symbol :scalar
[sym oldsym newsym]
(if (= sym oldsym) newsym sym))
4.memozie
(declare m f)
(defn m
[n]
(if (zero? n)
0
(- n (f (m (dec n))))))
(defn f
[n]
(if (zero? n)
1
(- n (m (f (dec n))))))
(def m (memoize m))
(def f (memoize f))
(println (time (m 100)))