显然,关于 Python 是否需要尾调用优化引起了很大的争论。当有人因为 Guido 没有“得到它”而向 Guido 发送了一份 SICP 副本时,这种情况就出现了。我和圭多在同一条船上。我了解尾调用优化的概念。我只是想不出 Python 真正需要它的任何原因。
为了让我更容易理解,有人可以给我一段使用 TCO 可以大大简化的代码片段吗?
显然,关于 Python 是否需要尾调用优化引起了很大的争论。当有人因为 Guido 没有“得到它”而向 Guido 发送了一份 SICP 副本时,这种情况就出现了。我和圭多在同一条船上。我了解尾调用优化的概念。我只是想不出 Python 真正需要它的任何原因。
为了让我更容易理解,有人可以给我一段使用 TCO 可以大大简化的代码片段吗?
就个人而言,我非常重视尾调用优化;但主要是因为它使递归与迭代一样有效(或使迭代成为递归的子集)。在简约语言中,您可以获得巨大的表达能力,而不会牺牲性能。
在“实用”语言(如 Python)中,OTOH,对于几乎所有可以想象的情况,通常都有很多其他的结构,所以它不那么重要。当然,考虑到不可预见的情况,拥有它总是一件好事。
就个人而言,我非常重视尾调用优化;但主要是因为它使递归与迭代一样有效(或使迭代成为递归的子集)。在简约语言中,您可以获得巨大的表达能力,而不会牺牲性能。
在“实用”语言(如 Python)中,OTOH,对于几乎所有可以想象的情况,通常都有很多其他的结构,所以它不那么重要。当然,考虑到不可预见的情况,拥有它总是一件好事。
如果您非常想对可能表示为循环的事物使用递归,那么“尾调用优化”确实是必须的。然而,Python 的仁慈独裁者终生 (BDFL) Guido 坚信循环被表示为循环——因此他不会进行特殊情况的尾调用(牺牲堆栈跟踪转储和调试规律性)。
尾调用优化使编写递归函数更容易,而不必担心堆栈溢出:
def fac(n, result=1):
if n > 1:
return fac(n - 1, n * result)
return result
如果没有尾调用优化,用大数字调用它可能会溢出堆栈。
Guido 在后续帖子中认识到,TCO 允许更简洁地将状态机实现为递归调用彼此的函数集合。然而,在同一篇文章中,他提出了一种没有 TCO 的、同样清洁的替代解决方案。