再帰的呼び出し
リスト5に、S式を与えると対応するHTMLを出力するプログラムを示します。それでは、各関数の処理について説明していきましょう。
まずは、print-htmlです。これは、1つのHTML要素に対応する処理を行います。与えられたeがリストなら、最初の要素がタグ名なので
のような開始タグを表示し、残りのリストは入れ子になったHTML要素の並びかもしれないので、HTML要素の並びを処理するprint-html-listを呼び出します。そして、
のような終了タグ表示します。
carは引数のリストの最初の要素を返す関数です。cdrは引数のリストの最初の要素を取り除いたリストを返す関数です。displayは引数の値を表示する関数で、printと異なり改行は表示されません。
次に、print-html-listについて解説します。
これは、HTML要素の並び(リスト)の処理を行います。引数のリストが空でない場合は、最初のHTML要素をprint-htmlに渡し、1つの処理をしてもらいます。残りのリストは自分自身を呼び出すことで処理します。
print-html-listはprint-html-listを再帰的に呼び出しています。Javaなどの言語では、再帰的な呼び出しはスタックを大量に消費するので避けられる傾向があります。Gauche(Scheme)では、このような再帰呼び出しはループに変換されて実行されるので心配なく使えます。
null?は引数のリストが空なら真(#t)、空でなければ偽(#f)を戻す関数です。
次に、print-open-tag、print-close-tagについて解説しましょう。これは、
や
のような開始タグ、終了タグ表示します。
24~29行目は広域変数gauche-pageを定義し値としてS式で表したHTMLを代入しています。'(xxx ...)の先頭のシングルクオート「'」は構文糖で(quote (xxx...))の略記です、quote は(xxx...)を評価(計算)せずそのままを値とするスペシャルフォームです。
31行目は、S式で表したHTML構造をprint-html関数に渡し、通常のHTMLに変換します。
結果は
Gauche Web・・・のように1行で出力されますが、HTMLが正しく作られていることが分かると思います。
print-html-listとprint-htmlはお互いを呼び出すことで再帰的に処理を行っていきます。データが入れ子(=再帰的)になっている場合は、処理するプログラムも再帰的に書くことでプログラムがシンプルになります。このような再帰的な呼び出しを使わずに繰り返しで処理しようとすると、かなり煩雑なプログラムになりますなることがあります。
まとめ
今回はここまでです。Gauche(Lisp/Scheme)のプログラムは関数の集まりでとてもシンプルに短く書けることがお分かりいただけたでしょうか。またS式はさまざまなデータ構造を表現でき、それを処理するプログラムも再帰的呼び出しを使うことでシンプルに書けます。
次回は、いよいよWebアプリらしいコードを書いていきたいと思います。
最後に、記事の理解を深めるための書籍として、「プログラミングGauche(オライリージャパン刊)」、参考サイトとしてGauche(http://practical-scheme.net/gauche/index-j.html)、Gaucheプログラミング(立読み版)(http://karetta.jp/book-cover/gauche-hacks)を紹介します。