在Scala 2.8.x中,添加了新的注释(@tailrec),如果编译器无法对带注释的方法执行尾部调用优化,则会产生编译时错误。

Clojure中是否有关于loop/recur的类似设施?

编辑:
在阅读了我的问题的第一个答案(感谢Bozhidar Batsov)并进一步搜索Clojure文档之后,我发现了以下内容:

(递归*)
依次评估exprs,然后并行地将递归点的绑定(bind)重新绑定(bind)到exprs的值。如果递归点是fn方法,则它将重新绑定(bind)参数。如果递归点是一个循环,则它将重新绑定(bind)循环绑定(bind)。执行然后跳回到递归点。递归表达式必须与递归点的精确度完全匹配。特别是,如果递归点是可变参数fn方法的顶部,则不会聚集其余的args-应该传递单个seq(或null)。在尾部位置以外重复出现是错误。

请注意,reclo是Clojure中唯一不消耗堆栈的循环构造。没有尾调用优化,并且不建议将自调用用于未知范围的循环。 recur具有功能,并且在编译器中验证了其在尾部位置的使用[重点是我的]。

(def factorial
  (fn [n]
    (loop [cnt n acc 1]
       (if (zero? cnt)
            acc
          (recur (dec cnt) (* acc cnt))))))

最佳答案

当您使用循环/重复AFAIK时,没有尾部调用优化。来自官方文档的报价:

关于Clojure警告/关于尾部调用优化失败的错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2712898/

10-10 01:51