末尾再帰たん萌え
たとえばF#で階乗をつぎみたいに実装したとするよね↓
let fact n res = if n = 0 then res else fact (n-1) (n*res)
なんだけど、末尾再帰って最適化されちゃうんだよね?特にSchemeとかだと。
たとえばさっきの階乗をC風に書けば
int fact(int n, int res) { if(n == 0) return res; else return fact(n-1, n*res); }
こんな感じだけど、もしこれがコンパイラとかによって最適化されちゃうとさ、
int fact(int n, int res) { while(true) { if(n == 0) return res; else { n = n-1; res = n*res; } } }
みたいになるの?末尾再帰たんは居なくなっちゃうの?
「末尾再帰たんは、どこへいっちゃったの?」
――『きっと、どこか遠いところへいってしまったんだよ。』
「とおいところって、どこ?」
――『今はまだ分からないだろう。』
「もう会えないの?」
――『大人になって、いつかパフォーマンスを気にするときが来るだろう。そうすれば、きっと末尾再帰がどこへいってしまったのか分かるさ。』
「ぜったい?」
――『ああ。大人になってメモリの事情なんかを知るときっとね。』
まあ、具体的に末尾再帰がどう最適化されてるんだろうなっていうお話。