2005年04月29日
川俣晶の縁側ソフトウェア技術雑記 total 3448 count

大好きなawkをXSLTと一緒にしないで! awkとXSLTは似ている、という意見への反論!?

Written By: 川俣 晶連絡先

 awkとXSLTは似ている、とよく言われます。

 私も、昔はそう思い、発言したこともあります。

 しかし、今では、それは違うのではないかと思うようになっています。

 それは漠然とした思いでしたが、ある雑誌記事を見て、それが自分の中で明確化されました。

 Java World誌 2005年6月号の「XMLボキャブラリ 理論と実践 第45回 簡単なXML処理を手軽に行うために」(檜山正幸著)に以下のように書かれています。

p154より

強いて言えばXSLTがAWKに当たるだろうか。組み込みの制御機構を持ち、"パターン&アクション"というパラダイムで処理が進む点で、両者はどことなく似ている。

 ここに書かれた文章は、けして間違ってはいないと思います。

 このような価値基準で比較した場合、確かに両者には共通点が見出せます。

 しかし、FORTRANとJavaは、命令を逐次的に実行するという共通点を持つために、似たプログラム言語である、と言い切ってしまうことが(厳密には間違いではないとしても)実用上不適切であるのと同じように、awkとXSLTを似ているという主張は不適切であると思うわけです。

"パターン&アクション"という共通性 §

 awkとXSLTは、"パターン&アクション"という共通性を持っています。

 つまり、いずれの言語で記述するコードも、流れて来るデータを捕まえる網(パターン)を張り巡らせ、網に掛かったデータが発生して初めてアクションが駆動されます。

 このような構造は、どのコードがどの段階で、どの順番で実行されるかが分かりにくいため、コードの総量が増えると極度に分かりにくくなる危険性があります。しかし、僅かなコードで大きな成果を得るには、有力なスタイルだと思います。

 このような観点で、awkとXSLTは共通の特徴を持っていると見て良いと思います。

組み込みの制御機構の相違 §

 「組み込みの制御機構」というものが厳密に何か分かりませんが、パターンのマッチを判定し、自動的にアクションを呼び出すメカニズムであると判断して、話を進めます。

 awkとXSLTは、どちらもこれを持ちます。

 その点で、共通の特徴を持っていると言えます。

 しかし!

 ここがポイントです!!

 awkとXSLTが持っている制御機構の振る舞いは、致命的に異なっています。

 awkの制御機構は、基本的に、指定された入力から1行ごとにデータを読み取り、それをパターンとマッチします。入力はシーケンシャルに行われます。別の言い方をすれば、この制御機構は、全ての行を列挙するイテレータによって構築されていると言えます。

 それに対して、XSLTの制御機構は、基本的にxsl:apply-templates要素によって指定されたノード群に対して発動されます。つまり、このノード群を列挙するイテレータによって構成されていると言えます。暗黙的なデフォルトのテンプレートの存在によって、あたかも全てのノードを列挙するイテレータが存在するかのような雰囲気も漂いますが、あくまで雰囲気に過ぎません。これはいともたやすく動作を上書きできます。

 つまり、以下のような相違があると言うことです。

 awkは、特別なコーディングをしない限り、全ての入力行をそれぞれ1度だけ扱います。その順番も明快に決まっています。

 しかし、XSLTは、全てのノードを扱うかどうかはコードの書き方次第です。どのノードをどのような順番で扱うかは、コードによって決定され、2回以上扱われるノードもあれば、1回も扱われないノードも発生します。つまり、どのノードがどのような順番で扱われるか、明快には決まっていません。この特徴は、先に述べた「どのコードがどの段階で、どの順番で実行されるかが分かりにくい」という特徴と相乗効果を生み、分かりにくさを増大させます。

とりあえずの結論 §

 以上のような理由から、XSLTのコードは、規模が大きくなると爆発的に「動作を理解すること」の困難さが増大することが考えられます。これは私自身の経験からも肯定できます。

このような問題を回避するために、とりあえず私が選択しているのは、xsl:call-template要素の多用です。xsl:apply-template要素と違って、xsl:call-template要素はそれによって引き起こされる処理の内容が明確に分かります。しかし、xsl:call-template要素を使うということは、"パターン&アクション"というモデルを放棄することとイコールです。つまり、この段階で、awkとの類似性は消えます。

 これに対して、awkは、あくまで入力行をシーケンシャルに処理するシンプルな制御機構が前提となるため、規模が大きくなっても分かりにくさはさほど増大はしません。

 もちろん、awkは機能が少ないために処理が複雑化するとトリックを多用し、その結果分かりにさが増大する可能性はあり得ます。これは私の経験からも肯定できます (汗。

 以上のような話から"パターン&アクション"を行う場合には、パターンの判定を行う対象を列挙するメカニズムは、単純なモデルであることが望ましい、という仮説が立てられます。

そして、元の記事に戻る §

 実は、この結論は、これを書く切っ掛けになった記事の内容と重なります。

 というよりも、むしろ、それを読んだからこそ、このような文章が書けたとも言えます。

 この記事では、XML文書をもっと楽に扱うためには、ツリーをシーケンシャルに列挙するイテレータが有効であるとしています。

 awkはシーケンシャルに列挙するイテレータによって駆動されますが、XSLTは違います。

 それゆえに、XML版のawkとは、ツリーをシーケンシャルに列挙するイテレータによって駆動されるものではないか、というアイデアが導き出されます。