OCamlをつつく5ー再帰関数。ループは再帰、それが関数型のやり方さ。
*iterは再帰関数*
let hello max =
let rec iter count =
if count < max then begin
if count = 0 then Printf.printf "hello indre\n";
print_int count;
print_string "\t";
iter ( count + 1 )
end
in
iter 0;;
hello 10;;
Printf.printf "good-by";;
再帰関数の宣言文がどこだか分かったかな?再帰関数の宣言は let rec iter countの部分ピヨ。つまり次の形式になっているんだ。
let rec 関数名 インスタンス名
関数名にの他にインスタンス名(便宜上のボクが付けた表記)なんて少し変だけど、その代わり関数も変数と同じ様に扱えるのがOCamlの強みなので我慢しよう。
ところで、「何でコメントをlet rec iter count = の部分につけないの」と思った人も居ると思うけど、それをすると文法エラーになるんピヨ。 OCamlは残念ながらコメントが使いづらいね。
※コメントの部分はコピーしちゃ駄目だよ。エラーになるから。
あと、命令型言語の使い手が気になるのはパフォーマンスだと思う。C言語の使い手たちは、関数呼び出しのオーバーヘッドがを心配すると思うけど、OCamlには末尾再帰という機能があって、関数呼び出しをジャンプ命令としてコンパイルするからパフォーマンスが劣化しないらしい。えっ?何で疑問文なのかって?それは、ボクがまだ確かめていないからピヨ。翻訳されたアセンブリを見てないうちは確信を持っていえないし、Windowsはパフォーマンス上不利だと公式ページに明記されているからね。Windowsは残念ながらまだ作りこまれていない様だ。気が向いたらボクが実装しようかな♪
ここまでの説明で「末尾再帰があるからループの代わりにバリバリ使おう」と思った人には残念なお知らせがあるピヨ。それは、末尾再帰にも条件があるんだ。その条件とは、 最後は必ず自分を呼ぶ事ピヨ。この条件は結構難しいよね。ボクもHelloをプログラミングした時困ったよ。でもせっかく関数型言語を楽習しているんだから、なるべくループを使わずに、末尾再帰を意識してプログラミングをしよう。