2020年6月30日火曜日

SmartDox

前回の記事ではModegrammingをキーワードにしたモデル駆動開発向けに開発している5つのプロダクトについて説明しました。

SmartDox
文書処理系
SimpleModeler
モデルコンパイラ
Kaleidox
アクション言語
Arcadia
Webフレームワーク
Prefer Cloud Platform
クラウド・アプリケーション・プラットフォーム

今回は、この中のSmartDoxについて紹介します。

SmartDoc

2000年ごろに文書処理系のOSSであるSmartDocを開発していました。

SmartDocはXML形式のSmartDoc文書で記述したソースから、HTML、PDF(Tex経由)、プレインテキストを生成します。

SmartDocは個人用文書作成ツールとして便利に使っていたのですが、モデル駆動開発のDSLの基盤としても活用できないか、検討を重ねてきました。というのは、文芸的プログラミング(literate programming)をモデル駆動に適用した文芸的モデリング(literate modeling)の実現しようと考えたからです。

文言的モデリングを実現するためには、モデルの内容を説明した文章とモデル定義を同一のプレインテキスト内に自然な形で同居させる必要があります。

モデル記述言語

Modegrammingにおけるモデル駆動開発を行うためのモデル記述言語を考えた場合、前述した文芸的モデリングが重要な要素になります。

一方オブジェクト指向モデリング言語のデファクトであるUMLは、以下のような理由でモデル駆動開発で本格活用するのは難しいのではないか、と個人的に考えています。

  • UMLはグラフィカル言語であるためモデルの入力が煩雑
  • グラフィカル言語は大規模モデルの編集が難しい

また、UMLの編集に専用ツールが必要、というのも運用上の問題点です。

格納形式も独自形式になるので、UMLモデルを作成したツールでしか編集することができません。商用製品の場合、製品にロックインされることになるため、経費がかかることに加えて、将来製品が販売停止になった時にはモデルの再利用や保守などにも問題がでてきそうです。

格納形式が独自形式になることで、テキストベースのバージョン管理システムで管理することが難しくなるという問題もあります。

このようにグラフィカル言語のUMLを、本格的な開発に適用することは色々と問題がありますが、その一方でUMLで定義しているオブジェクト・モデルのメタ・モデルは業界標準としてのコンセンサスがとれているものなので活用したいところです。

以上のことを考えると、モデル駆動開発向けのモデリング言語として以下の要件に行き着きました。

  • プレインテキストでモデル定義とモデルの説明文を文芸的モデリング的に同居できる
  • UMLのメタ・モデルをベースにしている

これを実現するためのメタメタモデルとしてSmartDocが活用できないかと考えたわけです。

SmartDox

SmartDoxはOSSで開発しているSmartDoc後継の文書処理系です。

モデル駆動開発のためのモデリング言語のDSLを構築するためのメタメタモデルを提供しています。

同時に、本来の機能である文書処理系にもSmartDocと同様の機能セットを提供することを目標にしています。本ブログもSmartDoxで書いたものをBlogger形式に変換しています。

SmartDoxはEmacs org形式をベースにMarkdownとHTML、XMLの文法をマージした文法を定義しました。

SmartDocはXMLベースでしたが、SmartDoxはプレインテキストベースの文書形式になっています。近年はMarkdownによるプレインテキストがソフトウェア開発での文章作成のデファクトになっているのでMarkdownを取り入れています。また、ボクが通常Emacs上でEmacs orgモードで文章作成しているのでEmacs org形式もサポートしています。ざっくりいうとEmacs org形式とMarkdown双方の緩い上位互換をとりつつ、拡張文法としてHTMLやXMLによる詳細指定を可能にした文法になっています。

このSmartDox文法によって、以下の3種類の文書を構築する構成要素が得られます。

  • セクションの入れ子による木構造
  • テーブルによる表構造
  • マークアップ付き自然言語

この中で「セクションの入れ子による木構造」と「テーブルによる表構造」をモデル駆動開発におけるモデル記述のメタメタモデルとして使用するのがSmartDoxによるモデル記述の基本アイデアになっています。

また「マークアップ付き自然言語」によってモデルに対する説明文をモデル記述内に自然に配置することができます。

SmartDoxベースのDSL

SmartDoxによるDSL基盤を使ってSimpleModelerとKaleidoxを実装しています。

SimpleModeler

SimpleModelerはモデル駆動開発に用いるモデルコンパイラです。

元々ScalaのDSL機能を用いてモデル定義をする方式を主にしていましたが、現在開発中の新バージョンよりSmartDoxベースのモデル記述方法に一本化しました。

SimpleModelerのモデル定義の例を以下に示します。

#+title: サンプル

SimpleModelerのサンプルです。
以下のようにコンパイルします。

```
$ sm java sample.org
```

* Resource

** Person

#+caption: 特性一覧
| 特性 | 名前    | 型      | 多重度 | ラベル | カラム | データ型 | 備考 |
|------+---------+---------+--------+--------+--------+----------+------|
| 属性 | name    | token   |      1 |        |        |          |      |
| 関連 | address | Address |      1 |        |        |          |      |

** Address

#+caption: 特性一覧
| 特性 | 名前 | 型    | 多重度 | ラベル | カラム | データ型 | 備考 |
|------+------+-------+--------+--------+--------+----------+------|
| 属性 | zip  | token | ?      |        |        |          |      |

リソース・エンティティの2つクラスPersonとAddressを定義しています。

SmartDoxのセクションの階層構造を利用してクラス種別のResourceとその配下にクラスPersonとAddressを定義しています。

Kaleidox

次の例はモデル駆動開発向けのアクション言語Kaleidoxです。

Kaleidoxでは、スクリプトを用途ごとに文法の違う複数のセクションで構成する構造になっています。

Kaleidoxのスクリプトの例を以下に示します。

* description

Kaleidoxでモデルを使用する例です。

* env

db.default.driver="org.h2.Driver"
db.default.url="jdbc:h2:mem:"

* voucher

** user

#+caption: 特性一覧
| 特性 | 名前 | 型     | 多重度 | ラベル  |
|------+------+--------+--------+---------|
| 属性 | id   | int    |      1 | User ID |
| 属性 | name | string |      1 | 名前    |
| 属性 | age  | int    |      ? | 年齢    |

* main
(store-query 'user nil)

スクリプト全体はSmartDoxの文法によって記述されており、プログラムを記述するmainセクションにKaleidoxのスクリプトが書かれています。

以下の例はdescription, env, voucher, mainの4つのセクションで構成されたKaleidoxスクリプトです。

descriptionセクションはスクリプトの説明を書くセクションです。SmartDox形式のプレインテキストを記述します。

envセクションはスクリプト実行時の環境変数をHOCON(typesafe config)形式で定義します。

voucherセクションはVoucherステレオタイプを持ったクラスを定義するセクションです。SimpleModeler形式の表形式でモデルを記述します。

mainセクションはスクリプト本体をKaleidoxスクリプト形式(S式)で記述します。

以上から分かる通り、各セクションの構造はSmartDoxのセクションを利用し、自然言語による記述を行うセクションではSmartDox形式を用いています。

まとめ

今回はオブジェクトモデル記述のためのDSL基盤の側面からSmartDoxについて紹介しました。

次回はSimpleModelerの紹介をする予定です。