等の例題を説いていると、よく再帰による実装を見かけます。等の書籍にも、可能な限り再帰的な考え方で実装しろと書かれています。「再帰でばかり実装すると、スタック領域を食いつぶしてしまうんじゃないのか?」という不安があります。基本的に、関数呼び出しの際は、現在実行している関数の情報(レジスタ情報や引数・戻り先のポインタ)を、メモリ上のスタック領域と呼ばれるところに押し込んでいくので、再帰はスタック階層が深くなり、かの有名なスタックオーバーフローエラーが出ることになります。階乗(n!)を実装します。実装すると以下のようになります。fact関数を呼び出しており、エラーログ的にも優しくありません。関数の最後の処理として自分自身を呼び出す再帰関数(これを末尾再帰と言う)を検知すると、パラメーターを新しい値に更新した後、再帰呼び出しを関数の冒頭にジャンプするコードに書き換えるしくみがあるみたいです。末尾再帰を検知すると、内部的にはwhile文に変換している。捉えても大きな違いはなさそう。実際にfact関数を末尾再帰にしてみる。部分で、この処理を別の関数として置き換え、その関数を再帰的に呼び出すように修正します。呼び出すだけになっている。うまく実行してくれるようになります。アノテーションを利用します。っぽいものを実際に実装して挙動を追ってみるこんにちは。