言語内 DSL を考える。

プログラミング言語内 DSL についての議論。メインは @kmizu さんと @yukihiro_matz さんのつぶやき。マクロを使った構文の拡張の話。またその構文を利用するシーンを含めた話題など。
マクロ Ruby プログラミング言語 DSL
12
Kota Mizushima @kmizu
いきなりだけど言語語り。自分の理想とする言語は、ユーザによる抽象化の試みを可能な限り邪魔しないと同時に、「破れにくい」抽象化層を簡単に構築できる言語であって欲しい。
Kota Mizushima @kmizu
「破れにくい」というのはどういうことかというと、いわゆるマクロを持っている言語の多くに共通する話だと思うのだけど、定義されたマクロを間違った、あるいは想定外の使い方をした場合に、その中身、つまり展開結果がユーザに漏れてしまうのは駄目だと思うのだ。
Kota Mizushima @kmizu
もちろん、マクロの作成者が細心の注意を払って、マクロを誤った使い方をした場合に適切なエラーメッセージを出すという事は可能だ。しかし、それをするために努力しなければいけないのは嬉しくない。
Kota Mizushima @kmizu
マクロに限った話ではなくて、いわゆる言語内言語(EDSL)全般に言える話なんだけど、正しく使っている間は、ちゃんとEDSLとして振舞うし、ユーザにもそう見えるのだけど、間違った使い方をすると途端に内部の実装が露出する、なんてのはダメダメ。
Kota Mizushima @kmizu
そのようにして定義された構文(っぽいもの)は1級の構文ではなく、2級の構文だと言いたい。声を大にして言いたい。
Yoichi Hirai @pirapira
@kmizu パターンマッチに漏れがあると検出してくれる言語ありますね。そんな感じで、マクロの呼び出され具合をすべて網羅してエラーを吐くかなにするかを定義しないと、この場合になにをすればいいかわからん、と、検出してくれるといいですかね。
Kota Mizushima @kmizu
@pirapira なるほど。そっちの方向では考えてませんでした。「ちゃんとした」マクロを書くようにユーザに警告するシステムという方向性ですね。自分が考えていたのはもうちょい保守的な方向で、なんらかの制約記述言語をマクロに導入したらいいのではないかなとか。
Yukihiro Matsumoto @yukihiro_matz
興味深い。RubyのDSLではむしろ後付構文(っぽいもの)が2級市民である故にかえってわかりやすい気がします。それではよくない、と? RT @kmizu: そのようにして定義された構文(っぽいもの)は1級の構文ではなく、2級の構文だと言いたい。声を大にして言いたい。
Kota Mizushima @kmizu
マクロのような機構によって言語の構文を拡張できる。これはいい。だけどそれだけでは駄目で、その構文の制約条件を構文の定義者が簡単な形で書けるようなシステムであって欲しい。
Yukihiro Matsumoto @yukihiro_matz
@kmizu 結局、状況・アプリに応じて言語そのものをどんどん拡張していく(元の言語? なにそれ)というキャンプと、安定したコアがなければ不安じゃないかというキャンプの違いってことなのかなあ。
Yusuke KUOKA @mumoshu
@kmizu ただの構文木のプリプロセッサではだめで、例えば文法とその意味を直接的にコンパイラに教えるような機構があってほしい、ってことですか?
Kota Mizushima @kmizu
まあ偉そうに書いておいて、そのようなシステムを自分の言語に未だに実装できてないわけですがorz
Yusuke KUOKA @mumoshu
@kmizu 理想は大事だと思います!
Kota Mizushima @kmizu
@mumoshu えてるのは、マクロの引数や返り値に、制約条件を何らかの形で書ける専用の言語を導入したいといったことです。たとえば、マクロに対するこの引数はlvalue(だと評価し得る値)でなければいけない、とか。
Yusuke KUOKA @mumoshu
@kmizu ふむふむ・・・なんとなく考え方の方向性は同じな気がします^^;
Kota Mizushima @kmizu
@mumoshu 問題なのは、制約記述言語がどの程度リッチであれば十分なのか、というところで、これはまだよくわからないです。
Yusuke KUOKA @mumoshu
@kmizu マクロにシグネチャを持たせたい、という話と解釈したのですが、それはScalaみたいな冗長性の少ない静的型付け言語でDSLを定義するのとは違うんですかね?
Kota Mizushima @kmizu
@yukihiro_matz たぶん、Ruby(に限らないですが)によるEDSLでは、想定外の使い方をされたときに内部実装がユーザに露出してしまいますよね?自分の主張は、DSLの実装は基本的には(ユーザが望まない限り)ユーザからは隠蔽されているべきだ、という主張です。
NISHIMOTO Keisuke @keisuke_n
@kmizu 私もScalaでDSLを仮に作ってみて同じ感想を抱きました。ただやってみて思うのは定外の使い方を検出するのが難しいこと、そして警告やエラーメッセージに必要な情報が思ったより少ないことなどが問題になりました。
NISHIMOTO Keisuke @keisuke_n
@kmizu たぶん一定以上の境界を超えた場合は新たに言語を作ったほうがいいのかもしれません。DSLの(本体言語を提供者・ユーザが使える)利点を消してしまいますが...。
NISHIMOTO Keisuke @keisuke_n
@kmizu ああ忘れていましたがInternal DSLの話ですね。
Yukihiro Matsumoto @yukihiro_matz
@kmizu EDSLってなんだろう? External DSL だとすると実装が漏れるかどうかは、DSLの実装次第だし。Internal DSLの間違い?
Kota Mizushima @kmizu
@yukihiro_matz すいません。Embedded DSL(埋め込みDSL)の略の意味でした(どこかのブログで見かけた)が、ぐぐってみたらあんまり一般的でない用法だったようで。Internal DSLの事でとりあえず良いです。
Yukihiro Matsumoto @yukihiro_matz
@kmizu Internal DSLだと仮定して話すと、独立した実装を持つExternal DSLでなく、言語文法を「濫用する」Internal DSLを選択するのは、ホスト言語の機能を最大限活用したいだけでなく、DSL全体の挙動をホスト言語の観点で理解したいというのもあります
Yukihiro Matsumoto @yukihiro_matz
@kmizu ということは、内部実装が露出するのは必ずしも忌むべきものではなかったりするのではないかと。ケースによっては。ホスト言語に全く関心のないDSLユーザーには向かないタイプのDSLですね。
残りを読む(17)

コメント

ログインして広告を非表示にする
ログインして広告を非表示にする