Bal*_*rdi 5 tail-recursion clojure tail-call-optimization
我有以下Clojure代码来计算具有某种"可以考虑"属性的数字.(代码究竟做了什么是次要的).
(defn factor-9
([]
(let [digits (take 9 (iterate #(inc %) 1))
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))))))
Run Code Online (Sandbox Code Playgroud)
现在,我进入TCO并意识到如果使用recur关键字明确告知Clojure只能提供尾递归.所以我重写了代码来做到这一点(用recur代替因子9是唯一的区别):
(defn factor-9
([]
(let [digits (take 9 (iterate #(inc %) 1))
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))))))
Run Code Online (Sandbox Code Playgroud)
据我所知,TCO有双重好处.第一个是它不像非尾递归调用那样使用堆栈,因此不会在更大的递归上使用堆栈.第二,我认为因此它可以更快,因为它可以转换为循环.
现在,我已经做了一个非常粗略的基准测试,但两个实现之间没有看到任何差异.我的第二个假设是错误的还是这与在JVM上运行(没有自动TCO)和recur使用技巧来实现它有关?
谢谢.