在 Scala 2.8.x 中,@tailrec
添加了一个新的注解 ( ),如果编译器无法对注解的方法执行尾调用优化,则会给出编译时错误。
Clojure 中是否有一些类似的设施loop/recur
?
编辑: 在阅读了我的问题的第一个答案(感谢 Bozhidar Batsov)并在 Clojure 文档中进一步搜索后,我发现了这个:
(recur exprs*)
按顺序计算 expr,然后并行地将递归点的绑定重新绑定到 expr 的值。如果递归点是一个 fn 方法,那么它会重新绑定参数。如果递归点是一个循环,那么它会重新绑定循环绑定。然后执行跳回到递归点。递归表达式必须与递归点的数量完全匹配。特别是,如果递归点是可变参数 fn 方法的顶部,则不会收集其余参数 - 应该传递单个 seq(或 null)。recur in other than a tail position 是错误的。
请注意,recur 是 Clojure 中唯一不消耗堆栈的循环结构。没有尾调用优化,不鼓励使用自调用来循环未知边界。recur 是功能性的,它在尾部位置的使用由编译器验证[重点是我的]。
(def factorial
(fn [n]
(loop [cnt n acc 1]
(if (zero? cnt)
acc
(recur (dec cnt) (* acc cnt))))))