Erlang的递归函数不仅仅是goto吗? [英] Is Erlang's recursive functions not just a goto?

查看:86
本文介绍了Erlang的递归函数不仅仅是goto吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是让它直指我。考虑下面的Erlang代码示例:

Just to get it straight in my head. Consider this example bit of Erlang code:

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

不是调用test()只是转到了吗?

Isn't the test() call, just a goto?

之所以这样问,是因为在C语言中我们了解到,如果执行函数调用,则返回位置始终放在堆栈中。我无法想象在Erlang中一定是这种情况,因为这会导致堆栈溢出。

I ask this because in C we learned, if you do a function call, the return location is always put on the stack. I can't imagine this must be the case in Erlang here since this would result in a stackoverflow.

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

We had 2 different ways of calling functions: goto and gosub. goto just steered the program flow somewhere else, and gosub remembered where you came from so you could return.

鉴于这种思维方式,我可以看看Erlang的递归比较容易,因为如果我只是阅读:test()作为goto,那么根本没有问题。

Given this way of thinking, I can look at Erlang's recursion easier, since if I just read: test() as a goto, then there is no problem at all.

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

hence my question: isn't :Erlang just using a goto instead of remembering the return address on a stack?

编辑:

只是为了阐明我的观点:

Just to clarify my point:

我知道goto可以在某些语言中用于跳转到各处。但是只是顺从而不是做someFunction(),您也可以做:goto someFunction()
在第一个示例中,流程返回,在第二个示例中,该流程仅在someFunction中继续,并且永不返回。

I know goto's can be used in some languages to jump all over the place. But just supose instead of doing someFunction() you can also do: goto someFunction() in the first example the flow returns, in the second example the flow just continues in someFunction and never returns.

因此,我们仅通过跳转到方法起点即可限制正常的GOTO行为。

So we limit the normal GOTO behaviour by just being able to jump to method starting points.

如果您看到这样的话,

If you see it like this, than the Erlang recursive function call looks like a goto.

(我认为goto是无法返回您的来源的函数调用)。这正是Erlang示例中发生的事情。

(a goto in my opinion is a function call without the ability to return where you came from). Which is exactly what is happening in the Erlang example.

推荐答案

尾部递归调用更多地是返回并立即调用此其他函数,而不是goto,这是因为内部整理

A tail recursive call is more of a "return and immediately call this other function" than a goto because of the housekeeping that's performed.

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

Addressing your newest points: recording the return point is just one bit of housekeeping that's performed when a function is called. The return point is stored in the stack frame, the rest of which must be allocated and initialized (in a normal call), including the local variables and parameters. With tail recursion, a new frame doesn't need to be allocated and the return point doesn't need to be stored (the previous value works fine), but the rest of the housekeeping needs to be performed.

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

There's also housekeeping that needs to be performed when a function returns, which includes discarding locals and parameters (as part of the stack frame) and returning to the call point. During tail recursive call, the locals for the current function are discarded before invoking the new function, but no return happens.

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

Rather like how threads allow for lighter-weight context switching than processes, tail calls allow for lighter-weight function invocation, since some of the housekeeping can be skipped.

goto& NAME 语句更接近您的想法,但并不完全,因为它会丢弃本地人。为新调用的函数保留参数。

The "goto &NAME" statement in Perl is closer to what you're thinking of, but not quite, as it discards locals. Parameters are kept around for the newly invoked function.

另一个简单的区别是:尾调用只能跳转到函数入口,而goto可以跳转到大多数地方(某些语言限制了goto的目标,例如C,goto不能跳转到函数之外)。

One more, simple difference: a tail call can only jump to a function entry point, while a goto can jump most anywhere (some languages restrict the target of a goto, such as C, where goto can't jump outside a function).

这篇关于Erlang的递归函数不仅仅是goto吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆