I have the following Clojure code to calculate a number with a specific “factorizable” property. (what exactly the code does is secondary).
(defn factor-9
([]
(let [digits (take 9 (iterate
nums (map (fn [x] ,(Integer. (apply str x))) (permutations digits))]
(some (fn [x] (and (factor-9 x) x)) nums)))
([n]
(or
(= 1 (count (str n)))
(and (divisible-by-length n) (factor-9 (quot n 10))))))
Now I am in TCO and understand that Clojure can only provide tail recursion, if explicitly said so using the keyword recur. So I rewrote the code to do this (replacing factor-9 with repetition being the only difference):
(defn factor-9
([]
(let [digits (take 9 (iterate
nums (map (fn [x] ,(Integer. (apply str x))) (permutations digits))]
(some (fn [x] (and (factor-9 x) x)) nums)))
([n]
(or
(= 1 (count (str n)))
(and (divisible-by-length n) (recur (quot n 10))))))
As far as I know, TCO has a double benefit. The first is that it does not use the stack as much as a non-tail-recursive call, and therefore does not introduce it into large recursions. Secondly, I think that therefore it is faster since it can be converted to a loop.
. - JVM ( TCO) recur ?
.