gpt4 book ai didi

recursion - Erlang 的递归函数不只是一个 goto 吗?

转载 作者:行者123 更新时间:2023-12-04 02:34:26 26 4
gpt4 key购买 nike

只是为了让它直接进入我的脑海。考虑这个 Erlang 代码示例:

 test() ->
receive
{From, whatever} ->
%% do something
test();
{From, somethingelse} ->
%% do something else
test();
end.

不是 test() 调用,只是一个 goto 吗?

我问这个是因为在 C 中我们学到了,如果你做一个函数调用,返回位置总是放在堆栈上。我无法想象这一定是 Erlang 的情况,因为这会导致计算器溢出。

我们有两种不同的调用函数的方式:
goto 和 gosub。
goto 只是将程序流程引导到其他地方,gosub 会记住您来自哪里,以便您可以返回。

有了这种思维方式,我可以更轻松地查看 Erlang 的递归,因为如果我只是将: test() 读为 goto,则完全没有问题。

因此我的问题是:不是 :Erlang 只是使用 goto 而不是记住堆栈上的返回地址吗?

编辑:

只是为了澄清我的观点:

我知道在某些语言中可以使用 goto 来到处跳转。但只是假设而不是做 someFunction() 你也可以这样做: goto someFunction()
在第一个示例中,流程返回,在第二个示例中,流程仅在 someFunction 中继续并且永不返回。

因此,我们只能通过跳转到方法起点来限制正常的 GOTO 行为。

如果你这样看,那么 Erlang 递归函数调用看起来就像一个 goto。

(在我看来,goto 是一个无法返回您来自何处的函数调用)。这正是 Erlang 示例中发生的事情。

最佳答案

由于执行的内务处理,尾递归调用更像是“返回并立即调用其他函数”而不是 goto。

解决您的最新问题:记录返回点只是在调用函数时执行的一项内务处理。返回点存储在堆栈帧中,其余部分必须分配和初始化(在正常调用中),包括局部变量和参数。使用尾递归,不需要分配新的帧,也不需要存储返回点(以前的值工作正常),但需要执行其余的内务处理。

还有一些需要在函数返回时执行的内务处理,包括丢弃局部变量和参数(作为堆栈帧的一部分)并返回到调用点。在尾递归调用期间,当前函数的局部变量在调用新函数之前被丢弃,但不会发生返回。

就像线程允许比进程更轻量级的上下文切换一样,尾调用允许更轻量级的函数调用,因为可以跳过一些内务处理。

Perl 中的“ goto &NAME ”语句更接近您的想法,但不完全是,因为它丢弃了本地变量。为新调用的函数保留参数。

还有一个简单的区别:尾调用只能跳转到函数入口点,而goto 最多可以跳转到任何地方(有些语言限制goto 的目标,例如C,goto 不能跳转到函数外)。

关于recursion - Erlang 的递归函数不只是一个 goto 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1483405/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com