ついて考えてみたりCの配列だったら、ポインタをひとつずらしてみたり全部考えなくても良い。再帰のすばらしいところは1から10まで考える必要がないことです。n番目とn+1番目の関係を見い出すだけで問題が解けてしまうのです。ところで、中学校くらいで「数学的帰納法による証明」を習いましたよね。N=0のときに正しいことを示す。N=Mのときに正しければN=M+1にも正しいことを示す。これも問題の再帰的な性質を利用して、全体は考えずにN番目とN+1番目に着目して命題を証明する、というものでした。この問題の場合、はnが1になったら和が1、自動的に終わりですね。その条件を加えてみます。}これで、再帰関数完成です。ここでこのブログエントリをしめくくってしまいたい気持ちはあるのですが、ちょっとまった。「計算の途中の式」、が大量にできてしまうため、nが大きくなるとそのうちスタックを食い潰してしまいます。試しにやってみましょう。nをばかでかくするとStackOverflowErrorとなります。末尾再帰その対策として、scalaでは再帰を「末尾再帰」という形にすることが推奨されます。「再帰関数の最後が自分の呼びだしのみになっている」という状態です。末尾再帰にすると良いのでしょうか。それは末尾再帰はループに書きなおすことができるからです。末尾再帰の関数を書くと、処理系が内部で勝手にループにしてくれるらしいです。ループならスタックがあふれることはないですよね。これを末尾再帰の最適化、と言います。ちなみに、例えばEmacsLispは、末尾再帰の最適化をしてくれません。自分はEmacsLispをよく触っているので、末尾再帰?なにそれ?って感じでした。Scalaは末尾再帰最適化をしてくれます。状態変数ともあれ、末尾再帰にする方法です。再帰関数の引数に「状態変数」とか「累積変数」とか呼ばれるものを付け足します。}ここではresultが状態変数です。このresultに計算の途中結果を格納して回します。すれば、再帰的な呼びだしを行なった結果がそのまま結果になります。これが末尾再帰関数です。なんかこれが再帰って、変な感じというか、テクいというか。個人的にはこれあんまり美しくないなあ、さっきのほうがきれいだなあって思うんですが。@tailrecは末尾再帰を強制するアノテーションらしいです。@kirisさんに教えてもらいました。これをつけると、末尾再帰になっていないとエラーになります。上述の再帰のポイントに従って再帰関数を書き、末尾再帰にできる場合は末尾再帰に最適化する、のが定石、ということです。最後に再帰関数を書くのは楽しいのですが、1から10までの和を求めるのに再帰を使うとか、そういうことはやめましょう。sum適切なアルゴリズムを選ぶのが大事です。Blog|ブログを報告する。