Tag: tail call optimization

为什么Scala编译器不应用尾部调用优化,除非方法是最终的?

为什么Scala编译器不应用尾部调用优化,除非方法是最终的? 例如,这个: class C { @tailrec def fact(n: Int, result: Int): Int = if(n == 0) result else fact(n – 1, n * result) } 结果是 错误:无法优化@tailrec注释的方法:它既不是私有也不是最终的,因此可以被覆盖 如果编译器在这种情况下应用TCO ,究竟会出现什么问题呢?

为什么代码会主动尝试阻止尾部呼叫优化?

这个问题的标题可能有点奇怪,但事实是,就我所知,根本就没有什么能说明跟尾部优化有关。 然而,在浏览开源项目时,我已经遇到了一些主动尝试阻止编译器进行尾部调用优化的函数,例如CFRunLoopRef的实现,它充满了这样的黑客攻击 。 例如: static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline)); static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { if (func) { func(observer, activity, info); } getpid(); // thwart tail-call optimization } 我很想知道为什么这看起来如此重要,是否有任何情况下我作为​​一个正常的开发人员应该保持这种心态呢? 例如。 尾部呼叫优化有常见的缺陷吗?

如何在没有尾部调用优化的情况下使用函数式编程replacereplacewhile循环?

我在我的JavaScript中尝试更多function的风格; 因此,我已经用循环replace了诸如map和reduce之类的效用函数。 但是,我还没有findwhile循环的function替代,因为tail调用优化通常不适用于JavaScript。 (从我所了解的ES6防止尾部调用溢出堆栈,但不会优化其性能。) 我解释了我在下面试过的,但是TLDR是:如果我没有tail调用优化,while循环实现的function是什么? 我曾经尝试过: 创build一个“while”实用程序function: function while(func, test, data) { const newData = func(data); if(test(newData)) { return newData; } else { return while(func, test, newData); } } 由于尾部调用优化不可用,我可以将其重写为: function while(func, test, data) { let newData = *copy the data somehow* while(test(newData)) { newData = func(newData); } return newData; } 然而在这一点上,我觉得我已经使我的代码更复杂/混淆谁使用它,因为我必须拖动一个自定义的实用function。 我看到的唯一的实际优势是它迫使我使循环纯净; 但似乎只是使用一个常规的while循环更直接,并确保我保持一切纯净。 我也试图找出一种方法来创build一个模仿recursion/循环效应的生成器函数,然后使用find或reduce之类的效用函数对其进行迭代。 […]

为什么JVM仍然不支持tail-call优化?

两年之后,这个function似乎有了一个原型 实现 , MLVM已经把function列为“原型80%”了一段时间了。 Sun和Oracle在支持尾部呼叫方面没有积极的兴趣,或者只是尾部呼叫“ 在每个function优先级列表中被排在第二位 ”,正如JVM语言峰会 ? 如果有人testing了MLVM构build,并且可以分享一些它的工作效果(如果有的话),我会非常感兴趣。 更新: 请注意,像Avian这样的虚拟机支持正确的tail-calls,没有任何问题。

Haskell有尾recursion优化吗?

我在今天发现了unix中的“time”命令,并认为我会用它来检查Haskell中的尾recursion函数和正常recursion函数之间的运行时间差异。 我写了以下function: –tail recursive fac :: (Integral a) => a -> a fac x = fac' x 1 where fac' 1 y = y fac' xy = fac' (x-1) (x*y) –normal recursive facSlow :: (Integral a) => a -> a facSlow 1 = 1 facSlow x = x * facSlow (x-1) 记住这些是完全用于这个项目的,所以我没有费心检查零或负数。 但是,在为每个方法编写一个主要方法时,编译它们并使用“time”命令运行它们,都具有与正常recursion函数相似的运行时间。 这与我在Lisp中关于尾recursion优化方面所听到的相反。 这是什么原因?