4

由于 .net 有TailCall操作码,如果 F# 函数是真正的尾递归,这可以用来确定吗?

如果是真的,有没有人制作了一个识别尾函数和非尾函数的 VS 插件?

4

2 回答 2

6

有关 F# 如何编译尾调用的摘要,请参阅F# 团队博客上的这篇博文。

简而言之,

  1. 直接递归尾调用通常转换为循环。
  2. 相互递归和间接非递归尾调用通常会转换为 .NET 尾调用。

但请参阅完整帖子了解所有血腥细节。

于 2012-03-14T01:28:15.157 回答
3

是的,如果编译器发出tailcall 指令,那么该调用将是尾递归的(从 CLR 4 开始,但仍有一些例外,它实际上不会是尾递归的)。但这并不一定意味着整个函数都是尾递归的。例如,我可以想象 QuickSort 函数编译后,第一个递归调用不是尾递归,而第二个是尾递归。

另外,仅仅因为某些函数不包含tail指令,并不一定意味着它不是尾递归的。tail即使没有指令,JIT 编译器也可以识别尾调用并对其进行优化。

此外,F# 编译器有时会以非递归方式编译递归函数。tail这与普通的尾调用优化和不使用指令有些不同,但总体效果相似。

于 2012-03-14T01:32:58.477 回答