uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

[Groovy][DSL]DSLについて

DSLすなわちDomain Specific Language(特定[業務]領域特化型言語)は最近良く聞く言葉です。

でも、バズワードっぽくて、多少とっつきが悪いのではないでしょうか?ですよね?なのでちょっと解説を試みてみます。

DSLは何でないか

まず最初に、「DSLは何か」を考えるには、「DSLは何でないか」を考えることが良い助けになります。DSLは何でないかというと、「汎用言語/汎用記法」ではないのです。汎用言語/汎用記法とは、たとえばJavaC++RubyXMLなどですね。

汎用ではない言語とは例えば、組版言語であるTeXやPostScript、MathMLなど、VRMLとかです。これらはまさしくDSLと呼べるでしょう。HTMLや、JSPもそうです。

「特化」?

その上で、まず考えたいのは、対象業務領域への「特化」とは何かということです。

Cは比較的低レベル言語であり、システム記述に向いていますが、CはDSLなのでしょうか。あるいはFORTRAN数値計算のためのDSLなのでしょうか? ちょっと違う気がしますよね。DSLというには限定の度合いが少なく、特化しているという印象が薄い気がします。つまり、何かが「DSL」かどうかは、本質的な差(テクニカルにどういう機能を達成しているか)というよりも、業務に限定している度合いの「程度問題」であるといえます。あるいはその業務ごとに、個別に作っていくのだぞ、という「使い方の問題」や「気持ち」の問題なところもあります。

あるいは「(汎用言語ではできる)特定機能ができない」という機能の不存在がDSLらしさを強めるのかもしれません。

「言語」?

次に、DSLのLすなわち「Language」が意味するところは何かを考えてみます。

こと内部DSLに関しての「L」は、「完結したプログラミング言語」までは意味していません。トークンの使い方(100.meter)とか、表記を「英語っぽい」ようにするかどうかとか、「変数や制御構造をなるべく使わないで定数とメソッドコールで書き下していく」「メソッドチェインとかfluent interfaceで連ねていく」というような、これもLanguageぽくない「気持ちの問題」が周辺にはある気がします。これは、最近使われるDSLの用途として、プログラミングの素養が低いユーザーにもわかりやすくする、という事情がたまたまあるからだと思っています。

この目的を達成するのには、つまり良いDSLを作るのに寄与するのは、プログラミング言語としての純粋な「言語機能」に限りません。言語機能の用法(イディオムや技法)、ライブラリのメソッド名やクラス名のネーミングルールとかもDSLの構成要素となります。あるいは、フレームワークの設計もそうでしょう。何をテンプレートメソッドとして書かせるかという設計がDSLの目的に寄与しています。

この状況が意味しているのは、「DSLのL」は、特定の「プログラミング言語仕様/言語機能」に限定して考えるのではなく、「意図することを表すためのあらゆる手法の総体」つまり「言語運用体系」として考えるべきだ、ということです。

まとめ

DSLという語もしくは技術には、定義だけからは導けない、文脈をともなった結構広い意味がある。技術エリア、あるいは「傾向/指向/方向性/方法論」としてとらえた方が良い。

その上で、DSLについて考えるには、少なくとも以下の2レベルで分けて考えた方が良い。

  • DSLを、フレームワークや業務用ライブラリやプラグインの作りを含めた、業務モデリングの取り組みの総体として考えることができる。この場合、内部DSLを実現するための表記レベルとしての話だけで考えると不十分。
  • かたや、DSLを表記の工夫の問題としていうと、Groovyについては、オペレータのオーバーロード定義や、getter/setterの自動生成機能とかautoboxing/unboxingとか、ロジックを簡潔に書くための機能と同じ土俵にあリ、これらとの間に明々白々な区切りがある訳ではない。「これがDSL機能だ!」という範囲を明確にはいえない。

この両者はもちろん車の両輪です。後者の「言語機能としてのDSLサポート」については、独立した機能の集合なので、一個一個かんがえていけばよい。それらを最終的にどう選択し、どう組み合わせるかということはG*WS 4回で関谷さんが指摘してたように、「設計手法」だといえるでしょう。このブログではそれらをぼちぼちトピック的に考えたり紹介したりしていければなーと思います。

ちなみに、現時点で内部DSL設計のよい参考になると思うのは、Martin Fowler氏のThought Worksアンソロジーの「2 章 とある秘密基地とRuby による20 のDSL」ですかね。Rubyですけども、これをGroovyで一通り書いてみるのは良い勉強になると思います。

ちなみに以下によれば、RubyにはGroovyのクロージャのdelegateに相当するものが無いのでビルダー作りに苦労するそうです。

ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション

ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション

まとまってませんがこの辺で。