C#是否支持尾递归?

37

2
请查看此帖子https://dev59.com/HXRB5IYBdhLWcg3w26x3 - Ashley John
2
还有来自 MSDN 的这篇文章:http://blogs.msdn.com/b/davbr/archive/2007/06/20/tail-call-jit-conditions.aspx - Ashley John
C#规范没有提到TCO。 - user166390
我认为这更与编译器有关,而不是语言本身。 - V4Vendetta
@V4Vendetta 不完全是这样。编译器(和运行时)只是实现一种语言(可能带有错误、扩展和巧妙的优化)。如果没有语言提供的保证,试图猜测编译器/运行时/JIT在特定情况下会做什么(以及在稍微不同的环境中会做什么)将是一种令人恼火的练习。 - user166390
2个回答

14

C#语言本身不支持尾递归,但是这篇有趣的文章介绍了一种类似于trampolining的技术,可能有助于您解决问题。


6

很遗憾,目前C#还不支持尾递归。

我不确定C#标准本身是否规定了允许/禁止尾递归的内容。但是由于.Net支持尾递归,因此如果C#也能支持尾递归就太好了。

如果你真的需要在.Net语言中使用尾递归,请考虑使用F#作为替代方案。


1
它(.NET)可以做到。自CLR 2以来,32位和64位JITters都可以做到,但在.NET 4中得到了极大的改进。 - porges
尾递归优化只是一种优化。优化尾调用意味着运行时不再能够生成正确的堆栈跟踪(因为某些堆栈帧被优化省略)。如果C#编译器优化了尾调用,则代码将产生不正确的堆栈跟踪。来源:http://gbracha.blogspot.cz/2009/12/chased-by-ones-own-tail.html - user7610
@user7610 非常感谢您提供的参考资料,我很喜欢阅读它。然而,它实际上与您的陈述相矛盾,而不是支持。您声称“优化尾调用意味着运行时无法生成正确的堆栈跟踪”,但 Bracha 显示了完全相反的情况。他甚至说应该要求尾调用优化,并引用 Guy Steele 的文章,认为尾调用优化是完全支持面向对象抽象所必需的(我在这里找到了 Steele 的文章 here;原始链接已失效)。 - Ken Wayne VanderLinde
@KenWayneVanderLinde说,保留堆栈跟踪和良好的调试体验是一个问题。然后他提出了一些优化尾调用同时保持堆栈跟踪的想法。但是,给我展示一个实际实现任何这些想法的语言。既然没有,那就说明这并不简单。 - user7610
2
他说得对,尾调用优化应该是必需的。实际上,CLR支持尾调用正是因为他在博客末尾的第一个论点(Argument 1)所述的原因。“对于CLR 4来说,x64 JIT有时不会遵守“tail.”前缀,这导致像F#这样的函数式语言无法使用。因此,我们努力改进了x64 JIT,使其能够始终遵守“tail.”前缀,并帮助F#取得成功。”http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/tail-call-improvements-in-net-framework-4.aspx - user7610
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接