为什么Perl如此害怕“深度递归”? [英] Why is Perl so afraid of "deep recursion"?
问题描述
我最近偶然发现了这本书 高阶Perl ,它基本上建议了以功能方式在Perl中执行操作的方法。作者解释说,Perl具有 Lisp 的7个核心功能中的6个,而C有没有。
我有一个问题,看起来像一个递归解决方案的好候选人,我用这种方式编码。但Perl抱怨深度递归。我搜索了一下,发现一位Perl僧侣解释说Perl不是Haskell。显然,如果递归深度超过100个级别,默认情况下会有投诉。
有 是扩展此限制或关闭它的方法完全,但我的问题是:
- 是否有一个原因是Perl对递归过于紧张,而 Haskell 根本没有?
因为在Haskell中,我们有懒惰&保守的递归和尾调用优化,而Perl没有。
这实际上意味着每个函数调用都会分配一个称为堆栈的内存量,直到函数返回。当你编写递归代码时,由于这些嵌套的函数调用,你建立了大量的内存,并最终会堆栈溢出。 TCO允许未使用的块被优化。
没有这个,依靠递归并不是一个好主意。例如,假设您编写了 map
的递归版本,它会碰到任何体面大小的列表。在Haskell中,守护递归意味着对于大列表,递归解决方案比像函数这样的循环更快。
TLDR:Haskell's实现的目的是处理函数式/递归式的风格,而perl的实现不在早期,并且100个函数调用级别是一个理智的限制。
I recently stumbled across the book Higher-order Perl, which basically suggests ways to do things in Perl in a functional way. The author explains that Perl has 6 out of 7 core features of Lisp, while C has none.
I had a problem which looked like a good candidate for a recursive solution, and I coded it in this fashion. But Perl complained about "deep recursion". I googled a bit and found a Perl monk explaining that "Perl is not Haskell". Apperently you get a complaint by default, when the recursion depth exceeds 100 levels.
There are ways to extend this limit or to turn it off entirely, but my question is:
- Is there a reason that Perl is so uptight about recursion, while Haskell is not at all?
Because in Haskell, we have laziness & guarded recursion and tail call optimization and Perl has neither.
This essentially means that every function call allocates a set amount of memory called "the stack" until the function returns. When you write recursive code, you build up a huge amount of memory because of these nested function calls and eventually can stack overflow. TCO allows the unused chunks to be optimized away.
Without this it's not really a good idea to rely on recursion. For example, say you wrote a recursive version of map
, it'd crash with any decent sized list. In Haskell, guarded recursion means that with large lists, the recursive solution is much faster than a "loop" like function.
TLDR: Haskell's implementations are designed to handle a functional/recursive style and perl's implementation is not and back in the good old days, 100 levels of function calls was a sane limit.
这篇关于为什么Perl如此害怕“深度递归”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!