4

.netにはTailCallオペコードがあるので、これを使用して、F#関数が本当に末尾再帰であるかどうかを判断できますか?

それが本当なら、誰かがテール機能と非テール機能を識別するVSアドインを作成しましたか?

4

2 に答える 2

6

F# が末尾呼び出しをコンパイルする方法の概要については、F# チーム ブログのこのブログ投稿を参照してください。

要するに、

  1. 通常、直接再帰的な末尾呼び出しはループに変換されます。
  2. 相互再帰と間接的な非再帰的なテール コールは、通常、.NET テール コールに変換されます。

しかし、すべての悲惨な詳細については、完全な投稿を参照してください。

于 2012-03-14T01:28:15.157 に答える
3

はい、コンパイラがtailcall 命令を発行した場合、その呼び出しは末尾再帰になります (CLR 4 の時点では、実際には末尾再帰ではない例外がまだいくつかあります)。しかし、それは必ずしも関数全体が末尾再帰であることを意味するわけではありません。たとえば、最初の再帰呼び出しが末尾再帰ではなく、2 番目の呼び出しが末尾再帰になるようにコンパイルされた QuickSort 関数を想像できます。

また、一部の関数にtail命令が含まれていないからといって、必ずしも末尾再帰ではないというわけではありません。JIT コンパイラーは、tail命令がなくても末尾呼び出しを認識し、最適化することができます。

さらに、F# コンパイラは、再帰関数を非再帰的な方法でコンパイルすることがあります。これは、通常のテール コールの最適化とは多少異なり、tail命令は使用されませんが、全体的な効果は似ています。

于 2012-03-14T01:32:58.477 に答える