[英]Is there a way to explicitly write a elixir function to be tail call optimised?
In Clojure for example you can use the recur especial form to explicit the intention to use non-stack-consuming recursive calls, and is verified by the compiler. 例如,在Clojure中,您可以使用recur especial形式来明确使用非堆栈消耗递归调用的意图,并由编译器进行验证。 As it's wrote in the Clojure docs :
正如它在Clojure 文档中所写:
"recur in other than a tail position is an error", "recur is functional and its use in tail-position is verified by the compiler"
“在尾部位置以外的地方重复是一个错误”,“重复是功能性的,并且它在尾部位置的使用由编译器验证”
In elixir you can define a function as a series of clauses, with recursions calls between them. 在elixir中,您可以将函数定义为一系列子句,并在它们之间进行递归调用。 Is there a way to know for sure that the defined function is going to be tail call optimised?
有没有办法确定定义的函数将被尾部调用优化?
Compiler doesn't optimize a function . 编译器不优化函数 。 It optimizes a call to that function.
它优化了对该函数的调用 。 It may be the call to the same function inside it, it may be a call to different function, it doesn't matter.
它可能是对它内部相同函数的调用,它可能是对不同函数的调用,也没关系。
...which isn't the case with Clojure, where recur
can only return execution to the latest "recursion point" (be it loop
or fn
) which makes mutual recursion impossible without "help from the outside", such as a trampoline . ...这与Clojure的情况并非如此,其中
recur
只能将执行返回到最新的 “递归点”(无论是loop
还是fn
),这使得在没有“来自外部的帮助”(例如蹦床)的情况下相互递归是不可能的。 It's more like a bandaid than a solution, but the problem is too big and a proper solution would require too much. 它更像是一个bandaid而不是一个解决方案,但问题太大了,一个合适的解决方案需要太多。
Yes, there is a way to make sure it gets optimized in Elixir: it needs to be an actual tail call . 是的,有一种方法可以确保它在Elixir中得到优化: 它需要是一个真正的尾调用 。 That's all.
就这样。
In computer science, a tail call is a subroutine call performed as the final action of a procedure.
在计算机科学中,尾调用是作为过程的最终动作执行的子例程调用。
This can easily be determined by visually inspecting the code. 这可以通过目视检查代码轻松确定。
If Clojure were to work this way, the following two definitions would be equivalent: 如果Clojure以这种方式工作,以下两个定义将是等效的:
(defn x [] (x)) ; <- StackOverflowError if called
(defn x [] (recur)) ; <- hangs if called
But if you want to enforce this and fail otherwise, you have to do it either: 但是如果你想强制执行此操作而失败,则必须执行以下操作:
The latter seems more practical, easiest with pure functions. 后者似乎更实用,最简单的纯功能。
I haven't found any existing solutions that do that. 我还没有找到任何现有的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.