2011年3月31日木曜日

Asakusa Scala DSL

基幹バッチをターゲットにしたHadoopフレームワークAsakusaのScala DSLにトライしています。

DSLの素案が固まってきたので、SimpleModelerに組み込んでみました。

DSLを検証するために使用したモデルは、Asakusaのホワイトペーパーにある以下の図7です。
比較的シンプルですが、基幹バッチのデーターフローをモデルとして記述しています。


Asakusaでは、このようなデータフローをJava DSLで記述するわけですが、ここにScala DSLを用いるとより簡潔に記述できるのではないかと考えているわけです。

このデーターフローをScala DSLで記述したものが以下の会計処理バッチ.scalaです。
具体的な説明は追々していこうと思いますが、ここではぱっと見た感じ、簡潔に明快な形で記述できているような印象を持って頂けるとうれしいと思います。

このScala DSLの設計のポイントはScalaの型パラメータを使って、型安全にモデルを記述している点です。
少しの記述ミスでもコンパイラがエラーで教えてくれる点が、Scalaのような静的型付け言語をDSLのホスト言語として使用するメリットですが、型パラメータを使用することでこの長所を最大限に活かすことができます。

package sample

import org.simplemodeling.dsl.domain._
import org.simplemodeling.dsl.flow._

class 仕入明細データ extends DomainResource
class 仕入返品データ extends DomainResource
class 費用振替データ extends DomainResource
class 売価変更データ extends DomainResource

class 修正在庫振替TRN extends DataSet
class 修正未収収益TRN extends DataSet
class 修正在庫移動TRN extends DataSet
class 未払計上TRN extends DataSet

class 仕入TRN extends DataSet
class 在庫振替TRN extends DataSet
class 在庫移動TRN extends DataSet
class 未収収益TRN extends DataSet

class 計上済仕入TRN extends DataSet
class 計上済未収収益TRN extends DataSet
class 計上済未払費用TRN extends DataSet
class 更新済買掛残高TRN extends DataSet

class 請求エラーTRN extends DataSet
class 支払不可消込TRN extends DataSet
class 支払可消込TRN extends DataSet
class 照合済支払費用TRN extends DataSet
class 照合済未収収益TRN extends DataSet
class 照合済仕入TRN extends DataSet
class 照合済請求TRN extends DataSet

class 仕入データ extends DataSource4[仕入明細データ, 仕入返品データ,
                                     費用振替データ, 売価変更データ]
class 修正データ extends DataSource4[修正在庫振替TRN, 修正未収収益TRN,
                                     修正在庫移動TRN, 未払計上TRN]
class 売価変更在庫変更TRN extends DataSet
class 仕入データTRN extends DataSource4[仕入TRN, 在庫振替TRN,
                                        在庫移動TRN, 未収収益TRN]
class 残高更新TRN extends DataSource4[計上済仕入TRN, 計上済未収収益TRN,
                                      計上済未払費用TRN, 更新済買掛残高TRN]
class 請求TRN extends DataSet
class 会計データTRN extends DataSource7[請求エラーTRN, 支払不可消込TRN, 支払可消込TRN,
                                        照合済支払費用TRN, 照合済未収収益TRN,
                                        照合済仕入TRN, 照合済請求TRN]

case class 仕入データ取り込み(cout: Port[売価変更在庫変更TRN]) extends Operator12[仕入データ, 仕入データTRN, 売価変更在庫変更TRN](cout)
case class 残高更新(cin: Port[修正データ]) extends Operator21[仕入データTRN, 修正データ, 残高更新TRN](cin)
case class 照合処理(cin: Port[請求TRN]) extends Operator21[残高更新TRN, 請求TRN, 会計データTRN](cin)

// 図7 改善された会計処理バッチの処理フロー
case class 会計処理バッチ extends Flow32[仕入データ, 修正データ, 請求TRN,
                                    会計データTRN, 売価変更在庫変更TRN] {
  start op12(仕入データ取り込み(out2)) op21(残高更新(in2)) op21(照合処理(in3)) end
}

このScala DSLからSimpleModelerで生成したフロー図が以下のものです。
データフローの概要をつかむのに十分な図が得られていると思います。


このような図が生成できるということは、SimpleModelerの内部でデータフローのグラフ構造が適切に構築できたことを示しています。
このグラフ構造を使って、モデル検証を行ったり、モデルのクロスリファレンスを作成したり、さらにAsakusa Java DSLの自動生成を行うことが可能のはずです。

Asakusaでは、各種DSL向けにAsakusa Hadoopコンパイラの内部モデル(Asakusa IR?)が提供されるとのことなので、それを待ってAsakusa Hadoopコンパイラの連携部を作成していく予定です。