有没有办法显式编写一个 elixir 函数来优化尾调用?

Is there a way to explicitly write a elixir function to be tail call optimised?

例如,在 Clojure 中,您可以使用 recur especial form to explicit the intention to use non-stack-consuming recursive calls, and is verified by the compiler. As it's wrote in the Clojure docs:

"recur in other than a tail position is an error", "recur is functional and its use in tail-position is verified by the compiler"

在 elixir 中,您可以将函数定义为一系列子句,它们之间有递归调用。有没有办法确定定义的函数将被尾调用优化?

编译器没有优化函数。它优化了对该函数的 调用 。可能是在里面调用同一个函数,也可能是调用不同的函数,没关系。

...Clojure 不是这种情况,其中 recur 只能 return 执行到 latest "recursion point" (无论是 loop 还是 fn),这使得没有 "help from the outside" 就不可能进行相互递归,例如 trampoline。它更像是一个创可贴而不是一个解决方案,但问题太大了,一个合适的解决方案需要太多。

是的,有一种方法可以确保它在 Elixir 中得到优化:它需要是一个实际的 tail call。就这些了。

In computer science, a tail call is a subroutine call performed as the final action of a procedure.

这可以通过目视检查代码轻松确定。

如果 Clojure 以这种方式工作,则以下两个定义将是等效的:

(defn x [] (x))     ; <- WhosebugError if called
(defn x [] (recur)) ; <- hangs if called

但是如果你想强制执行这个并且否则失败,你必须这样做:

  • 编译前,e。 G。静态代码分析使用 "desired TCO"
  • 的一些标记
  • 部署前,e。 G。带有会触发堆栈溢出的测试

后者似乎更实用,使用纯函数最简单。

我还没有找到任何现有的解决方案。