Perl Hackers Hub

第35回Perlによる内部DSLの作り方(1)

本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーはcpanクライアントApp::cpmの開発などで知られる鍛治匠一さんで、テーマは「Perlによる内部DSLの作り方」です。

DSLとは

DSLDomain Specific Languageドメイン特化言語)とは、ある特定の問題領域に特化したコンピュータ言語のことで、汎用的なコンピュータ言語と対比されます。たとえば、

  • リレーショナルデータベースへの問い合わせに特化したSQL
  • ビルド手順記述に特化したMakefile
  • cpanモジュール依存記述に特化したcpanfile

などがDSLです。

DSLの利点

ではDSLの利点は何でしょうか。次の点が挙げられると思います。

簡潔である
適切なDSLを用いれば、問題を簡潔に記述できます。その結果わかりやすくなり、その問題の重要な部分に集中できます。
クールである
簡潔さとも関連しますが、適切なDSLは無駄なものが削ぎ落とされており、かっこ良くクールなものになります。DSLを人間が読み、開発するものである場合、クールさは非常に重要であると考えます。

DSLの欠点

DSLも、もちろん完璧ではありません。DSLの欠点として次の点があります。

問題領域を定義するのが難しい
DSLは特定の問題領域に特化した言語であると述べましたが、問題領域を定義することは非常に難しい作業です。問題領域の定義に失敗すると、DSLの範疇(はんちゅう)で扱えなくなる、DSLが冗長になるなどの問題が起こり、DSLの利点が失われてしまいます。
新たな言語を作るコストがかかる
新たな言語を作る以上、文法を考えそれを解釈するプログラムを作らなければならず、相当なコストがかかります。
新たな言語を習得するコストがかかる
使用者はその新たな言語を習得しなければなりません。さらにDSLという特性上、そこでの知識がほかに応用しにくいという問題も持っています。

これらの利点、欠点を理解し、適切な場面でDSLを使っていくことが重要です。

内部DSLと外部DSL

さて、DSLにはその形態において内部と外部があります。

内部DSL

内部DSLもしくは言語内DSLとは、ある汎用コンピュータ言語を用いて定義されたDSLです。また内部DSLを定義している汎用コンピュータ言語を、その内部DSLに対するホスト言語と呼びます。たとえば、

  • cpanfileはPerlをホスト言語として定義された内部DSL
  • RakefileはRubyをホスト言語として定義された内部DSL

などです。

内部DSLの利点としては次の3点が挙げられます。

1つ目は、新たな文法をゼロから作らなくてよいことです。ホスト言語の文法をそのまま拝借すればよいので、文法を自分で定義する必要はありません。

2つ目は、いつでも必要になる概念、処理がすでに用意されていることです。たとえば変数、制御構造、ループなどは、ある程度複雑な問題を扱う場合は必須です。それらはすでにホスト言語側で用意されているため、新たに作る必要がありません。

3つ目は、いざとなれば何でもできることです。これはちょっと反則ですが、問題領域を絞ってDSLを定義したはずなのにその問題領域から外れた処理をしたい場面が往々にしてあります。そんなとき内部DSLならば、ホスト言語の力を借りてほとんど何でもできます。

外部DSL

内部DSLに対して、独自の言語を用いて定義されたDSLを外部DSLもしくは言語外DSLと呼びます。たとえば、

  • SQL
  • Makefile

などが外部DSLです。

外部DSLの利点として、内部DSLに比べて、より問題領域に適したDSLとなり得ることが挙げられます。内部DSLでDSLを実装する場合には、いろいろなところでホスト言語の制約を受けます。外部DSLの場合はそういったことはなく、自由に実装できます。

欠点としては、新たな言語を作るのに非常にコストがかかることが挙げられます。

以降では、ホスト言語をPerlとした内部DSLについて説明していきます。

<続きの(2)こちら。>

おすすめ記事

記事・ニュース一覧