有没有办法显式编写一个 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。带有会触发堆栈溢出的测试
后者似乎更实用,使用纯函数最简单。
我还没有找到任何现有的解决方案。
例如,在 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。带有会触发堆栈溢出的测试
后者似乎更实用,使用纯函数最简单。
我还没有找到任何现有的解决方案。