Cogito Ergo Sum.

我思う故に我あり

関数の再帰呼び出し

 多くのプログラマを魅了するらしいのだが、僕自身は全く魅了されなかったプログラミングテクニックの1つに、「関数の再帰呼び出し」というものがある。関数の処理内容として自分自身を呼び出す、というテクニックを言う。

 僕自身がこのテクニックにハマらなかったのは、第1に、僕の書くプログラムがC言語文化に則った「関数を主体とした組み立て」になっていないからだろう。そもそも「一連の処理を関数に分割する」ということそのものをしない人なのだから、「再帰的な関数を書く」なんて凝ったことをするはずがない。

 ただ、僕が再帰処理に魅了されなかったのは、それだけの理由ではないような気がする。そもそも「再帰的な処理の何が面白いのか」がわからなかったのだ。

 プログラミング入門に載っている「再帰的関数の例」としては、「階乗」「ハノイの塔」「クイックソート」あたりが定番だと思う。

 このうち最も簡単なのは「階乗」だが、「自分の担当部分だけを処理して、あとは丸投げする」という方針で処理が上手く実現される、という面白さが僕にはよくわからなかった。

 今から考えてみれば、「繰り返し」が「for」や「while」のような繰り返し構文だけでなく、「関数の再帰的な呼び出し」によっても実現できる、というのは面白いポイントなのだけど、「階乗を求める」くらいなら「いつも通りforでやっても簡単に済む話なのに…」と僕にはピンとこなかった。「クイックソート」の例は上手いと思ったけれど、「ハノイの塔」は何だかお遊びにしか思えなかった。僕には「関数の再帰呼び出し」の使いどころ、というものがよくわからなかった。

 それが、関数型プログラミング言語を紹介しているWeb Pageや入門書の最初の方をチラチラ眺めていて、ようやくその使いどころがわかってきた。「再帰的な処理」が有効なのは「再帰的な構造のデータを処理するとき」なのだ。考えてみれば当たり前の話だ。

 「再帰的な構造のデータ」というのは、例えば、木構造。「あるフォルダ以下に存在する全サブフォルダと全ファイルを削除する」みたいな処理は、関数の再帰呼び出しで簡単に記述できる。また、これも概念的には木構造に対する処理と言っていいんじゃないかと思うんだけど、上述のクイックソートや二分探索。それから、「リスト」の処理。

 関数型プログラミング言語の親玉Lispの「Lisp」という言語名はずばり「LISt Processing」(リスト処理)の略で、Lispでは全てのデータが「リスト」として実現されている。この「リスト」なるものが再帰的構造をしているものだから、Lispによる一連の処理は関数呼び出しの繰り返しのかたちになる。それで、Lispのプログラムは必然的に括弧だらけになってしまう(このあたりわかったように書いてますが、極めて曖昧な記述に終始していますので、要注意。嘘もたくさん書いてると思う)。

 関数型言語についてはまだよくわかっていないのだけど、こういうこと知った上でRubyについて見直してみると、そこに(Rubyのウリの)オブジェクト指向の匂いだけでなく、関数型言語の匂いもプンプン感じる。1つ1つのプログラミング言語を実用的に使いこなせるようにならなくても、ちょっとずつカジっているだけで、こんな風にいろんなものが見えてくるのが面白い。これが僕の「プログラミング教養主義」。