recur 在内部 mapcat 终止,而 fn 呼叫版本等效吗?
recur
mapcat
fn
(def tree [1 [2 [3 5]] [6 [[1 2] [8 [9 10]]]]]) (defn leaves [node] (mapcat #(if (vector? %) (leaves %) [%]) node)) (leaves tree) ;; => (1 2 3 5 6 1 2 8 9 10) (defn leaves-with-recur [node] (mapcat #(if (vector? %) (recur %) [%]) node)) (leaves-with-recur tree) ;; Never terminates
如果使用 重现 是一个直截了当的不不,有没有什么理由让Clojure编译器不捕捉这个场景并警告程序员,甚至拒绝编译它?对于非尾部位置调用 重现 例如。
重现
#(if (vector? %) (recur %) [%])
是
(fn [%] (if (vector? %) (recur %) [%]))
recur 将递归到此匿名函数,而不是任何外部函数,并且由于它不会更改任何内容,因此这是一个无休止的循环。
至于警告,停车问题是众所周知的无法解决的,而且有可能陷入无休止的循环 编译时间