このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

厳密分離の原理とテンプレートエンジン

調査/作業の依頼とその報告が、恐ろしくガラス張りなことになっているんだけど:

NNDAスタイルってのはこういう事だから、まーいいや。背景として、僕がKuwataさんに「考えて欲しい」と言っていることを記しましょう。

テンプレートエンジンの構造

基本的な要求は、Webサイト/Webアプリケーション/Webサービスを作成する作業を比較的細かいタスクに分割して、それらを最適に(できるだけ最適に近く)配分・配置したい、ということ。配分・配置とは、人と時間のリソース空間における計画のことです。配分・配置の自由度を高めるには、タスクどおしの依存性が少なくて、並行的に作業できるのが望ましいですよね。打ち合わせや報告の負担も少なくしたい(どうせゼロにはできませんけど)。

こんな要求に対する基本原理となるのが、テレンス・パーの厳密分離(Strict Separation)だと僕は思っています。そのテレンス・パーの思想を直接的に具現化したのがStringTemplate言語/エンジンです。しかし、StringTemplateは、関数型言語を指向(むしろ志向)していたり、ソースコード生成も重視していたりします。そのため、Web制作目的では必ずしも使いやすくはないのです。

それで、StringTemplateに手を入れたいのですが、無闇に書き換えたりしてはいけません。基本は、StringTemplateのカスタマイズ・フレームワーク内でやりたい。ですが、今のStringTemplateは構文のカスタマイズ機構は持っていません。僕は構文のカスタマイズもしたいのですよ(理由は後述)。

幸いにもStringTempalateは、中間コード方式に近いらしいです。テンプレートエンジンは、ちゃんとした中間コード方式にすべきですよね。そうすれば、テンプレート構文の自由度を確保できます。可搬性の観点からは、中間コードも標準化されていて実装言語独立だといいんだけど、効率だの何だのの事情から実装言語依存もしょうがないかも。まー、ここらへんは折衷案や妥協案がいくつかあります。

いずれにしても、基本構造は次のようであるべき:

コンパイラ  : テンプレートファイル →  中間コード
展開エンジン: 中間コード → 出力データ(最終テキスト)

展開エンジンはひたすらテンプレート展開を処理します。余計なことをやってはダメです。例えば(構文はSmarty風)、{include file="../templates/footer.tpl"} を実行するとき、"../templates/footer.tpl" をオープンするとかは展開エンジンの仕事ではありません。パス名と実際のストレージ(またはストリーム)の関係がどうなっているかなんてのは実行環境によるので、パス名文字列からストリームへのリゾルブは外部環境への依頼(または外部環境からの注入;こっちが望ましい)とすべきですね。

構文のカスタマイズ

何故に構文のカスタマイズをしたいか? -- StringTemplateの構文に違和感を抱く人は多いと思います。そもそも構文とは、趣味嗜好による好き嫌いが出るもんです。「構文が嫌いだから使わない」という事態を避けるために、いくつかのフレーバーの構文を用意したいのです。

VM方式の言語は、原則として構文と実行系の分離が可能です。実際、JVM上で実行できる言語はいっぱりありますよね。ただし、上位構文と実行モデル/実行系が強く結びついていると、構文だけを差し替えるのは困難です -- Erlangはその例でしょう;ERTS上*1に別構文の言語は難しそう。

StringTemplateの場合は、実行モデルは単純だし、機能は“戦略的に貧弱”なので、テンプレート構文と実行系が強く結びついている事はないと思われます。よって、厳密分離の原理を遵守しながら、好みに応じて、SmartyのサブセットやDjango Templateのサブセットを使うのは可能じゃないかなー、というのが僕の思惑です。

*1:念のため、もう少し詳しく言うと; ERTSの中核にBEAMエミュレータがあります。BEAM(Bogdan/Bjorn's Erlang Abstract Machine)は仮想機械の仕様です。さらに、実際のErlang構文と仮想機械語を分離するために、Core Erlang という中間言語が設定されています。