みなさんは一つのプロジェクトでいくつの言語を使っているでしょうか。XML、Java、XSLT、HTML、CSS・・・と、数えてみるときっと多くの言語を使っていることでしょう。しかしそれらの言語を使っているのは、たまたまそれが主流だから、あるいは必要なフレームワークで使われているから、という理由からではないでしょうか。ある意味強制的に使わされているのです。そのような理由から、スタイルはCSS、設定なら通常XML、Webインターフェースの記述はHTML、と決められたことでしょう。しかしもし本当の多言語プログラミングを実践しようとすれば、言語の選択について真剣に考えて判断することになるはずです。
正しい判断をするには、多言語プログラミングを採用するのは、目の前にあるドメイン(問題領域)の問題について適切なプログラミング言語を選ぶためであるということを忘れてはいけません。しかしその場合問題になるのは、そのドメインあるいはサブドメインについて適切な言語を選ぶにはどうすればいいかということです。
まず第一に、利用可能な言語(事業プロジェクトにおいて製品環境やその他条件をクリアする言語)の性質を知ることが不可欠だと思います。言語の性質を知るということは単に長所短所を知るということ以上に、その言語が世界(モデル世界)をどう記述するか知るということです。そのためには言語の性質についてかなり深い分析が求められ、なかなか簡単なことではありません。
利用可能なプログラミング言語を理解する
プログラミング言語は有限の語彙とルールの集まりで、それらを組み立てて特定の問題を記述するものと考えることができます。また、自分たちの定めた問題をより良く記述できるかは、言語の構成要素とコンセプトに多くを依存します。このことからプログラミング言語にきわめて重要な側面が2つあることが分かります。それは1)語彙とルールの集合、2)使用可能な構成ルールです。
対象となるプログラミング言語のパラダイム(理論的枠組み)
表裏一体である語彙と構成ルールは、その言語の性質の大部分(あるいはマルチパラダイムなプログラミング言語における部分言語の性質)を決める枠組みであるパラダイムを作ります。
パラダイムは利用可能な言語について検討する上で重要な性質です。簡潔で可読性のいいコードを書くには適切なパラダイムを用いることが何より重要です。適切なパラダイムを用いることは問題となるドメインとソフトウェアモデルとを一致させる助けとなりますし、そのことで明確なモデルができ、より良い可読性も得られます。逆に、不適切なパラダイムを用いればほぼ間違いなく、その場しのぎのコードやトリッキーなコードを多く生み、コード量も爆発的に増加します(比較的単純なことをするにも多くのコード行が必要になるのです)。
プログラミングパラダイムの例
XML を例にとってみましょう。XMLは要素(element)の集まりとして表すことができ、各要素は内容(あるいはタグ)を持ちます。要素は他の要素へネストする(入れ子にする)ことができるので、一つの要素が他の要素を格納しそれぞれの要素に内容を与えることができます。この説明だけでXMLの性質と構成法が十分伝わるでしょう。つまり、XMLは入れ子構造を持ち、要素と内容から構成される、これだけで後のドメイン分析フェーズ(詳しくは以下で)で言語のパラダイムを考えるのに十分な情報になるのです。
別の例としてLuaを取り上げましょう。この言語が面白いのは構造のベースがテーブル形式であることです。Lua自体が他のテーブルを格納したテーブルであるともいえます。そのためテーブル型の形態を持つ言語といえ、テーブル型パラダイムと呼ぶこともできるでしょう。このことはLuaのパラダイムを十分表しているでしょうし、少なくともLuaについて最初に分析するには十分な助けとなります。
他の言語もこれと同じように見ていくことができます。Lispではデータ構造の多くがリストで、Lispプログラミングはリスト操作であると考えられ、それがこの言語の基底にあるパラダイムであると見ることもできます。またLispは関数型プログラミング言語で、関数を組み合わせて他の関数を作ることができます。このことは関数型のパラダイムを反映しています。Haskellも関数型プログラミング言語ですが、数学向けであるという特徴があります。この強い型付けをおこなう言語は抽象化で重要な役割をはたす強力な型システムをもち、そのことによってHaskellはかなりの抽象化能力を持ったかなり安全な言語となっています。Prologはほとんどが論理演算とアサーションから成り、 Prologという名前が表すように論理型プログラミング言語と呼び表すことができます。
その他のプログラミング言語の性質
パラダイムを考慮さえすれば、特定のサブドメインに対しての言語を選ぶ際に考慮すべき性質は他にそうありません。型付けの種類(動的/静的)や構文などは言語のパラダイムに比べれば重要度は低いのです。しかし考慮する必要はあります。この記事ではこれらの性質について掘り下げることはしません。ひとつアドバイスしておきますと、これらの性質を過大評価してパラダイム以上に重要視しないことです。パラダイムこそ対象となるサブドメインについてのコード表現力にとって重要な役割を担うものなのです。
異なる性質のサブドメインを見つけ定義する
ほとんどの人は多言語プログラミングについて考えているうちに大抵、対象とするドメインで使えそうないくつかの言語を選んでいるはずです。通常その選択は2つのことから決まります。つまり、ある種の言語はある種の問題に対してより有効であるという認識と、対象となるドメインは異なる部分部分をもち、場合によってはその各部分が異なる性質をもっているという分析結果です。
必然的に、対象となるドメインはサブドメインに分割することができます。この分割によって、ドメインは適当なレベルで区分され、それらのサブドメインの差異をはっきりさせることになります。とはいっても、それらはまだ相互にやり取りする必要がありますし、また、その相互作用を実装する時にそれぞれの違いを無視してもいけません。
ドメインをいくつかのサブドメインへ適切に分割すると、ドメインとプログラミング言語とを一致させる作業が容易になります。ドメインの問題のひとつは、それを一つの面から見るには大抵の場合大きすぎるものであることです。分割することで異なるサブドメインに異なるツールを使うきっかけができ、それによって適切なツールを使って問題をより良く抽象化したりデザインすることができるのです。
サブドメインとその性質を定めるのは簡単ではありません。そのためには分析スキルと対象となるドメインについての深い理解が必要になります。ドメインの専門家と一緒にこの部分だけでも作業するのは、サブドメインの性質について誤った結論を出してしまうのを防ぐのに有効なことです。この作業で大半をしめるのは、異なるサブドメインの性質と相互作用を見極めること、そして分かったサブドメインのパラダイムあるいは性質と呼ぶことのできるいくつかの概念と相互作用の形式を抽象することです。ドメインを理解し、その性質を見極めるのに役立つテクニックはいくつかあります。Eric Evans氏のドメイン駆動デザインにおけえるドメインクランチ(砕くこと)やJames Coplien氏のマルチパラダイムデザインなどはその一つです。
利用可能なプログラミングパラダイムを念頭に置いておくことは、利用可能なモデリング概念と整合するドメイン概念を形成するのに役立ちますが、問題分析を制約したりドメインの概念を自分の好きなパラダイムに押し込めてしまったりと、ドメイン理解に悪影響を与えるようであってはいけません。オブジェクト指向プログラミングにおいて、ドメイン概念がオブジェクトであると疑いなく考えてしまう時、このようなことが起きるのは珍しいことではありません。
サブドメインに適した言語/パラダイムを選ぶ
サブドメインを決めたので、今度は各サブドメインについて適切なプログラミング言語を選ぶ番です。適切なプログラミング言語とは何かを端的に表せば、サブドメインの問題をもっともうまく記述できる言語ということです。プログラミングをしている時に何か考える時、たいていは言語の影響を受けたり言語のもつ概念を通じて考えるものです。合わないプログラミング言語を使うとサブドメインについてのコードが読みにくくなったり不必要なものであふれたりしますが、適切なパラダイムを用いればサブドメインとプログラミング言語が一致させることができ、それにより簡潔で拡張しやすいコードができます。拡張性はパラダイムがぴったり合った時に得られる効果のうちでもっとも重要なものの一つです。ドメインというのは、たとえ発展があったとしても急にその性質を変えるものではありません。それ故に、ドメインはほとんどの場合同じパラダイムに沿って変化します。もし言語の性質がこのパラダイムに合っていれば、ドメインの発展などによる変化にかかるコストやドメインの範囲を制約するのにかかるコストを減らせると考えていいでしょう。
サブドメインとプログラミングパラダイムとの一致 -その例
Graphical User Interface
GUI について考えてみます。何かのインターフェースを見てみると、そこにはパネルがあり、その中にも他のパネルがあります。これらのパネルの中にはグラフィカルコンポーネント(ボタン、写真、枠など)があり、それらも他の部品をもち、その部品もまた他の部品をもつことができます。この簡単な分析からGUIがネスト(入れ子)の性質をもつことが分かります。モノを他のモノの中にネストすることができるのです。またGUIのコンポーネントにはプロパティがあります。これらのことから、GUIにはXMLのような言語が一番適しているように思えます。
しかしそう結論するのは性急ではないでしょうか。GUIの多くのことはXMLで表すことができるでしょうが、必ずしも全てを表せるとは限らないのではないでしょうか。 WPF(WindowsのGUIシステム)やXAML(XMLベースのGUI記述用言語)が良い例です。XAMLのXMLベースの構文は、上で述べたようにGUIのネストする性質に適したものです。しかし、たとえば要素のバインディングにはXMLベースでない特別な構文が使われています。GUIにはXML より適切な構文を使う方がメリットのあるサブドメインがあるのです。スタイルを例にすると、スタイルをXMLで表記してもタグの開始や終了はスタイルに関するサブドメインに関して意味をなさないため、多くの不要なものを加えるだけです。スタイルをより良く表記するには、スタイルの性質についてよく考えられた構文でないといけません。ではグラフィカルなスタイルを表記することの性質は何でしょうか?GUIのスタイルは、特有の名前で特定されるプロパティとそれが持つ値の組み合わせにすぎません。さらにスタイルは、プロパティがどの階層のコンポーネントのものであっても関係ありません。スタイルは単にプロパティの記述にすぎません。コンポーネントの方がその記述を判断するのです。コンポーネントがそうしなければスタイルはただ無視され何の影響も与えません。このちょっとした分析からでも、グラフィカルなスタイルというサブドメインに対してはCSSを構文に用いるのが良い選択になる理由がほぼ明らかになったのではないでしょうか。
ストリームとデータワークフローの処理
処理すべきアクションや情報あるいはデータのフローが起きたとしましょう。ほとんどの場合その流れは実質的にエンドレスです。そのフローに手を加え処理すると、それに続く別のアクションあるいは情報の流れができるからです。その例としてRSSフィード、HTTPリクエスト/レスポンス、ネットワーク信号があげられますし、ドメインを使ったその他さまざまなストリームもそうです。ここではストリーム指向のパラダイムの例をあげてしまいますが、ドメイン分析を十分おこなえばドメインにこの性質があるかを見極めるのはそれほど難しいことではありません。また、この性質を考慮するテクノロジを選択することはコードの整然さや可読性および品質をあげるのに役立ちます。もしそうしなければ、何層にもネストしたループやWhileブロックを書く羽目になり、モジュール性が失われてしまいます。
関数型言語、特にHaskellのような遅延評価をおこなう言語には無限のリストやストリームを扱うのに向いた性質があります。関数を連続させて明示的なワークフローを構築することは、ストリーム指向のパラダイムの一つのモジュールとなっています。
サブドメインに適したパラダイム -その他の例
ドメインと技術的手段としてのパラダイムとを適合させることが実際のツールを選ぶ上で欠かせない要素となるケースは他にも多くあります。多くのルールやバリデーション条件のあるドメインを伴うドメインでは、PrologやHaskellのような述語論理指向言語あるいは論理型言語を用いるメリットが大きいでしょう。並行性をベースにするサブドメインに対してはErlangのような並行プログラミング言語を、大量の文字列処理をおこなうドメインには強力な文字列処理パラダイムをもつプログラミング言語を使うことでメリットが得られるでしょう。
マルチパラダイムプログラミング言語
プログラミング言語には単一でなくいくつかのパラダイムをもつものもあります。しかしそれが最適なパラダイムを選択するのに役立つものであっても、多言語プログラミングの代わりとなるものでは決してありません。マルチパラダイムを実現するこの両方のアプローチにはどちらにも長所と短所があります。たとえば、多言語プログラミングを構成するような単一パラダイムの言語では、そのパラダイムに対して最も表現力のある構文を備えているでしょう。一方、マルチパラダイム言語では言語自体を設計する時点で複数のパラダイムが統合されています。後者の場合、複数のパラダイムを利用するのが容易という利点とともに、パラダイムの利用が暗黙的に強制されたりパラダイムについて無意識になるという欠点があります。またマルチパラダイムプログラミング言語は複雑になりがちです。しかしいくつかの言語(C#やC++)は主流になるという幸運を授かっています。
2つのアプローチのどちらを取るかを決める際には、これらのトレードオフやその他いろいろなことを考慮しないといけません。製品の都合上複数の言語を使うことのがあまり現実的でない場合(このようなことは少なくなってきていますし、主要なプラットフォームで使われる言語を使う分には問題なくなってきていますが)は、マルチパラダイム言語が良い選択肢になるでしょう。たとえ誰か(私自身も含め)がその正当性に異論を唱えたり問題をごまかしていると考えたとしても、チームメンバのスキルを鑑みて選択することもあるでしょう。
まとめ
階層ごとに言語を選ぶ、というような一般論を多言語プログラミングの理由にするのはやや単純化しすぎた物言いですし、プロジェクトで一つ以上の言語を使わざるをえないような問題がある時には直接的でもなく役に立つものでもありません。徹底的なドメイン分析と綿密なマルチパラダイム設計こそが多言語プログラミングの肝要です。プログラミング言語のパラダイムをサブドメインの性質に合わせることは、コードを可読性のある簡潔な変化に強いものにし、不要で分かりづらいものを避ける上でキーとなることです。プログラミング言語のパラダイムを理解し意識することは多言語プログラミングを最適化する最初のステップです。その次のステップでは、ドメイン駆動デザインとマルチパラダイムデザインのテクニックがプログラミングに関わってくるでしょう。
参考文献
James O. Coplien「Multi Paradigm Design(マルチパラダイムデザイン)」 (PDF
Eric Evans「Domain Driven Design(ドメイン駆動デザイン)」 (リンク)
筆者について
Sadek Drobi氏はエンタープライズアプリケーションの設計と実装を専門とするソフトウェアエンジニアです。ビジネスとディベロッパの橋渡しとなるソリューション(アジャイル、DSL、ドメイン駆動デザインなど)に関心があり、現在は言語指向プログラミングとマルチパラダイムデザインをテーマにした調査企画書に取り組んでいます。氏はValtech Consulting(リンク)のコンサルタントを勤めています。仕事だけでなく写真にも熱心で、www.sadekdrobi.com で技術的なブログを書く一方でhttp://photos.sadekdrobi.com では写真をこつこつと掲載しています。
原文はこちらです:http://www.infoq.com/articles/paradigm-based-polyglot-prog
(このArticleは2008年9月19日に原文が掲載されました)