问题标签 [tail-call]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
recursion - Prolog中的尾递归取幂
我正在尝试编写当 X 是系数、Y 是指数并且 R 应该返回答案时获得 3 个参数的代码。
到目前为止,我的代码是 -
我知道这行不通。
但我无法弄清楚。
java - Java中的尾递归优化和递归
我有一个关于尾调用优化的问题,我需要知道这个 java 代码的行为:
这段代码是一个无意义的例子,但我的问题是,在这种情况下:
- 第一个 doSomething() 调用会被优化吗?
- 第二个 doSomething() 调用会被优化吗?
- if/else 块以任何方式影响优化?
谢谢
编辑:
请提供一个示例,说明如果语言不是 Java 而是其他具有 TCO 的语言,您将如何做到这一点
f# - F# 尾调用因缺少括号而中断
在使用 F# 团队博客文章测试 F# 尾调用时,我发现几乎相同的代码具有相同的结果,但IL不同,尽管代码中只有括号不同。
下一个代码由编译器优化,我br.s IL_0000
在 IL 末尾看到并且没有调用sumSoFar
但是那部分没有被编译器优化,它已经call bla_bla.loopAndSum
接近 IL 的结尾。
这些示例的不同之处仅在于 . 周围的括号sumSoFar + x
。您可以使用它并在.NET Fiddle上查看 IL 。
有人知道为什么括号很重要吗?
haskell - 每个 Haskell 函数都进行尾调用吗?
我想知道 Haskell 中的每个函数都应该是尾递归的。
阶乘函数实现为非尾递归函数:
每个运算符也是一个函数,所以这相当于
但这显然是对我的尾声。我想知道如果每次调用都在堆上创建一个新的 thunk,为什么这段代码会导致堆栈溢出。我不应该堆溢出吗?
lua - 为什么我的尾调用函数不暂停和刷新输出?
我查看了lua-users Sleep Function参考,试图找到解决睡眠问题的非忙等待解决方案,但我对其中任何一个都不满意。尽管如此,我还是尝试使用几个来在使用尾调用的函数结束时提供延迟。
通常我不会使用尾调用,但由于 lua 不会为尾调用留下堆栈,所以它适合我。
不幸的是,我看到我的处理器使用率飙升至大约 20%,并且程序一旦开始就立即变得无响应,而没有任何输出刷新。
问题(简化)如下所示:
我已经尝试过套接字选择方法,os.execute,当然还有忙等待。其中只有忙碌的等待给出了预期的行为。
这些其他非忙等待解决方案也是非阻塞的吗?也就是说,尽管有延迟,他们是否允许处理尾调用?
如何刷新输出并让函数在恢复之前等待 10 秒而不忙于等待?
lua - luajit 无法钩住“tail return”
我们知道 Lua 有一个库函数debug.sethook
,当任何函数返回时,
都会通过事件“return”或“tail return”调用钩子函数,但 LuaJIT 不会钩子“tail return”。
有什么方法可以关闭LuaJIT的特化,让它钩“尾返回”?
recursion - 如何在列表中间插入,对尾调用友好但不影响性能?
所以我有这个似乎是非尾调用友好的功能,对吧?
然后我尝试弄清楚如何使用累加器,以便函数完成的最后一件事是调用自身,我想出了这个:
但是,据我了解, List.concat 的使用会使该功能的效率大大降低,对吗?那么我该如何正确地进行这种转换呢?
c - 尾递归 [C]
我书中的问题是“哪些递归调用(不是函数!)是尾递归的?”
在这个例子中,我猜第一个是尾递归的,但第二个不是。但是,在以下情况下会发生什么,我们printf()
在递归调用之前和之后也有?
考虑到我目前对尾递归的了解,我的猜测是第一个不是,但第二个和第三个是?我错了吗,如果是这样,你能解释一下这是如何工作的吗?
ecmascript-6 - 绑定函数是否支持 ES6 中的正确尾调用?
在 ECMAScript 2015 语言规范中, 和 的定义Function.prototype.apply
都Function.prototype.call
将“Perform PrepareForTailCall()”作为其步骤之一,因此我们知道这些函数支持正确的尾调用(即尾调用优化)。
但是,绑定函数对象上的 [[Call]]的定义省略了 PrepareForTailCall()。这是否意味着绑定函数不支持正确的尾调用,并且递归调用自身的绑定函数可能会炸毁堆栈?
recursion - Erlang、Last Call Optimization、lambda 函数以及如何防止堆栈增长
我正在编写一些 Erlang 代码,但我遇到了一个我不理解的奇怪情况。
编码:
输出:
根据我从这篇文章的理解,Erlang 使用了最后调用优化,如果一个函数做的最后一件事是调用另一个函数,那么 BeamVM 会将程序计数器跳转到新函数的开头,而不是推送一个新堆栈框架。这是否意味着在像上面这样的模式中,我们在堆周围而不是堆栈周围踩踏?这是否释放了之前在这些函数中保存的内存(在上述代码的情况下,我们是否会一次在内存中分配一个函数 F 的副本,或者我们是否会在内存中分配多个函数 F 的副本?一次)?使用这种模式是否有任何负面影响(除了明显的调试困难)?