Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
末尾再帰 - sumiiの日記
[go: Go Back, main page]

sumiiの日記 このページをアンテナに追加 RSSフィード

2007-08-15

末尾再帰

一部で微妙に:-)盛り上がっている件。単に「帰ってこなくて良い関数呼び出しをジャンプにする(ので、再帰呼び出しはループになる)」こと(いわゆる末尾呼び出し/末尾再帰)と、「メモリ消費が定数オーダーになる」ことを混同しているだけかと。

追記:いつも他人のふんどしだけでは恐縮なので情報提供(といっても、これも他人の研究ですが):CPS変換をすれば、すべての関数呼び出しは末尾呼び出しになります。が、(当然ながら)すべてのプログラムが定数メモリで動作するわけではなく、継続を表現するクロージャがヒープやスタックに確保されるだけで、メモリ消費は減少しません。

しかしながら、CPS変換をすると、末尾呼び出し最適化も簡単になります。「関数呼び出しf(x)の返り値yを継続kに渡す」というCPS項はf x (λy. k y)のようになりますが、λy. k yをη簡約するとkになるので、先のf x (λy. k y)はf x kとなり、末尾呼び出し最適化と同様にメモリ使用量が減少します。

…というようなことを学部時代のコンパイラ演習で習いました。元はこのあたりから辿れると思います。

ku-ma-meku-ma-me 2007/08/15 13:30 ぎゃあ、このエントリに気づかず向こうで同じツッコミをしてしまいました。
Haskell の実行モデル (?) においてはコールスタックの伸びとサンクの伸びを区別して考える合理的な理由がないので、Haskell の世界では「メモリ消費が定数オーダーになる」ことを「ループになる」と言う。というようなことをかつて誰かに言われてなんとなく信じてしまっていたのですが、誰に言われたのか思い出せません (笑)

ゲスト