3月10日(木)にAsakusa Scala DSL デザインレビューの勉強会に行ってきたので、そのメモ(感想)です。
(金曜日なら半徹もしくは翌日朝一番で書くところだけど、木曜日なのでtogetterにまとめるところだけ実施。改めて金曜日にメモを書こうと思っていたら、大地震が起きたので、予定より遅延…)
まず、この勉強会は『デザインレビュー』、つまり設計のレビュー。Asakusa FrameworkのScala DSLをどのように作っていくか?という話し合い。なので@asami224さんが作った現時点の「こんな感じでどう?」というサンプルが披露されたのであり、最終決定版が公開されたわけではない。
Asakusa DSLは(Model・)Operator DSL・Flow DSL・Batch DSLがあるけれども、今回はFlow DSLがターゲット。
つまりデータの入出力と処理順を記述するのが目的。
本家Java版ではアノテーションプロセッサー(apt)を使用しているけれども、Scala版は特にコンパイラプラグインを使っているという訳でもなく、アノテーションを使っている訳でもない。
普通に型パラメーターを使って記述する。
(Scalaコンパイラプラグインを使うと自分のDSLの独自エラーを出すことが出来るらしいが、プログラムは大変らしい)
型パラメーターを使っている理由は、コンパイル時に整合性をチェックする為。静的型付けはそれが利点なのは賛成。
フローに当てはまらないノード(型)を指定すると、コンパイルエラーになる。
今回はコンパイラーでチェックできるところまでで、作ったものをどう出力してAsakusa Frameworkにつなぐかについては未定(今のところはAsakusa DSLのJavaソースを出力する想定)。
これについて@ashigeruさんからAsakusa IR(Intermediate representation:中間表現)構想が披露された。各DSLはIR向けにデータを出力する。これによってJava・Scala以外のDSLも作れるというわけで、夢が広がりますな(笑)
(僕も何か作ってみようかな~。外部DSLになると思うけど。(チェックのことを考えなければ、それが一番楽だよね^^;))
asamiさんのScala DSLは型パラメーターを使っていて、場合によってその個数が異なる。
メソッドであればオーバーロードが出来る(同じメソッド名で引数の個数を変えられる)が、型パラメーターはそういう事が出来ない。なのでDataSource1[T1]、DataSource2[T1,T2]の様に、クラス名に数字を付けて別物にする。
これと統一させる意味もあると思うけど、メソッドにもproc12の様に数字を付けている。これは入力が1個、出力が2個という意味。(9個を超えたらどうするんだろう?)
数字を付けずにデフォルトの型を与えるような作りにすることも出来るらしいけど、エラーがあったときに候補がいっぱい出てくることになって分かりづらくなってしまう模様。それは確かに嫌だよね~。
メタスカラ(メタプログラミング)を使えば可変の型パラメーターっぽいものも扱えるようだけど、エラー時はとんでもないことになるらしい(爆)
自分は数字を付けること自体は止む無しかなぁと思う(ScalaにはTuple2とかFunction1とかがある)けれども、引数の個数とメソッドの数値を合わせる作業は、試行錯誤中にはつらいんじゃないかなぁ。
(ん? 設計時点でノード数は決まっているはずだから、そこは試行錯誤で変わることは無いのか?)
型パラメーターでノードを表すのではなく、インスタンスでノードを表す方式にするともっとすっきり書ける。というのを急遽@frsyukiさんが発表。
確かにこちらの方が分かり易い。ただ、インスタンスは同じクラスになるので、区別をつけることが出来ない。(フローの引数に指定した場合、本来なら異なるインスタンスを渡したらエラーにしたいところだが、コンパイル時には分からない)
チェックする為にはそれ用のプログラムを作る必要がある。
しかしながら、チェックするプログラムを自作するなら、わざわざJavaやScala上で(内部DSLで)作る必要ないよね(苦笑)
そうか、ひらめいた! つまり、インスタンス形式(frsyukiさん方式)で書いて、型パラメーター形式(asamiさん方式)のScalaプログラムを出力すればいいんだ!そうすればそちらでチェックされる(笑)
あと、ふとパス依存型を使ってインスタンスを作ったら区別できるんじゃないかな?とか思ったけど、具体的にどうすればいいかはノーアイデア…。
それから、日本語を使ってノード名やフロー名を表現しているのもポイントのひとつ。英語で書くと何を表しているのか分からなくなってきて、別途辞書が必要になったりするからね(苦笑)
ただ、日本語クラス名って何か問題があるんじゃない?って話が出ていた。jarファイル内はUTF-8にするのが仕様らしいから、問題ないはずって話だけど。
jarファイルにしない場合、例えばWindowsでコンパイルするとファイル名はShift_JIS(MS932)で作られる。これをEUCのUnixにそのまま持っていったりしたら、ダメそうな気はする。
もう一つの論点は、結局DSLをどのように使うのか?という本質的な問題。
設計書(図)を元にテキストに記述するのか、DSL上でプロトタイピングしつつ設計するのか、といった目的の違い。
個人的にはどうせ設計書では図を描くんだから、それと同じ形式の方が分かり易いと思うけど、プロトタイピングなら確かに図は後かも。
プロトタイピングで試行錯誤するなら、エラーがある場合はIDE上(コンパイル時)で即座に分かる方がいい。チェック用プログラムを作る方式は、その点では劣る。
大規模(ノードが1000個とか)なフローはGUIツールでは描けないというのはその通りだと思うけど、大規模だったらテキストで書いても結局分かりづらいよね^^;
そういうときは部分的に分割していくだろうから、どちらでも同じ気がする…。
※コメント投稿者のブログIDはブログ作成者のみに通知されます