常に再帰関数を反復関数に変換できますか?はい、絶対に、そして教会-チューリング論文は、記憶が役立つならばそれを証明します。一言で言えば、再帰関数で計算できるものは反復モデル(チューリングマシンなど)で計算でき、その逆も同様です。論文では変換の方法を正確に説明していませんが、それは間違いなく可能であると述べています。
多くの場合、再帰関数の変換は簡単です。Knuthは、「The Art of Computer Programming」でいくつかのテクニックを提供しています。そして多くの場合、再帰的に計算されるものは、より少ない時間とスペースで完全に異なるアプローチで計算できます。この典型的な例は、フィボナッチ数列またはそのシーケンスです。あなたはきっとあなたの学位計画でこの問題に出会ったでしょう。
このコインの裏側では、式の再帰的な定義を以前の結果をメモするための招待状として扱うほど高度なプログラミングシステムを確実に想像できます。これにより、コンピュータに正確にどの手順を指示するかをわずらわせることなく、速度のメリットを提供できます。再帰的な定義を使った式の計算を続けます。ダイクストラはほぼ間違いなくそのようなシステムを想像しました。彼は長い間、実装をプログラミング言語のセマンティクスから切り離そうとしていました。次に、彼の非決定的でマルチプロセッシングのプログラミング言語は、実践的なプロのプログラマーよりも優れています。
最終的な分析では、多くの関数が再帰的な形式で理解、読み取り、および書き込みが非常に簡単です。説得力のある理由がない限り、これらの関数を明示的に反復するアルゴリズムに(手動で)変換しないでください。コンピューターはそのジョブを正しく処理します。
説得力のある理由が1つあります。[ アスベストの下着を着用する ] Scheme、Lisp、Haskell、OCaml、Perl、Pascal などの超高級言語のプロトタイプシステムがあるとします。CまたはJavaでの実装が必要になるような条件があるとします。(おそらくそれは政治的なことです。)そうすれば、確かにいくつかの関数を再帰的に書くことができますが、文字どおりに変換すると、ランタイムシステムが爆発します。たとえば、Schemeでは無限テール再帰が可能ですが、同じイディオムが既存のC環境で問題を引き起こします。もう1つの例は、字句的にネストされた関数と静的スコープの使用です。Pascalではサポートされていますが、Cではサポートされていません。
このような状況では、元の言語に対する政治的抵抗を克服しようとする場合があります。Greenspun(頬の舌)の10番目の法則のように、Lispをうまく再実装していないことに気付くかもしれません。または、完全に異なるソリューションへのアプローチを見つけるだけかもしれません。しかし、いずれにしても、確かに方法があります。