TL; DR:功能语言比非功能语言处理递归的效果好吗?
我目前正在阅读Code Complete2。在本书的某些时候,作者警告我们有关递归的问题。他说,应尽可能避免这样做,并且使用递归的功能通常不如使用循环的解决方案有效。例如,作者使用递归编写了一个Java函数,以计算数字的阶乘(这样可能不完全相同,因为目前我没有这本书)。
public int factorial(int x) {
if (x <= 0)
return 1;
else
return x * factorial(x - 1);
}
这是一个不好的解决方案。但是,在函数式语言中,使用递归通常是首选的处理方式。例如,以下是Haskell中使用递归的阶乘函数:
factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n - 1)
并被广泛接受为一个好的解决方案。正如我所看到的,Haskell非常经常使用递归,并且我看不到它被皱眉的任何地方。
所以我的问题基本上是:
- 功能语言比非功能语言处理递归更好吗?
编辑:我知道我使用的示例不是最好的例子来说明我的问题。我只是想指出,Haskell(通常是功能语言)比非功能语言使用递归的频率更高。
factorial n = product [1..n]
更简洁,更有效,并且不会使堆栈大面积溢出n
(并且如果需要记忆,则需要完全不同的选项)。product
用some 定义fold
,它是递归定义的,但要格外小心。多数情况下,递归是可以接受的解决方案,但是错误/次优的做法仍然很容易。