Upload
nemoto-yusuke
View
836
Download
5
Embed Size (px)
Citation preview
実践プログラミング
DSLDomain-Specific Language
14年2月17日月曜日
Manning社の「~in Action」シリーズは色んなジャンル出てて良い感じですよ
14年2月17日月曜日
What Is DSL?
14年2月17日月曜日
What Is DSL?
DSL = Domain Specific Language
ドメイン特化言語
14年2月17日月曜日
Problem Domain Solution Domain
What Is DSL?What Is DSL?
14年2月17日月曜日
Problem Domain Solution Domain
What Is DSL?What Is DSL?
14年2月17日月曜日
Problem Domain Solution Domain
What Is DSL?What Is DSL?
14年2月17日月曜日
What Is DSL?
2009年のDSL開発者カンファレンスの基調講演においてファウラーは、他の汎用プログラミング言語とDSLを区別するものは「限定された表現力」だと話している
DSLスクリプトは下位に存在する実装を抽象化する
DSLは単なるAPIの集合ではない。これらのAPIはいずれも簡潔で、ドメインの語彙を用いている。
14年2月17日月曜日
I think DSL is ...(開発者でなく)ユーザーよりのコンパイラ?
14年2月17日月曜日
Implement DSL
14年2月17日月曜日
内部DSL
外部DSL
非テキストベースのDSL
・ 既存のホスト言語の上に実装されている・ 埋め込みDSL
・ 独立した言語として開発される・ 独立DSL
14年2月17日月曜日
内部DSL
外部DSL
非テキストベースのDSL
14年2月17日月曜日
内部 DSL・ 既存のホスト言語の上に実装されている・ 埋め込みDSL
14年2月17日月曜日
Example(Java)Smart API (Fluent Interface)
Person person = new Person();
person.setName(“taro”)
.setAge(28)
.build()
.say();
Is this smart...?
14年2月17日月曜日
内部DSLの実装パターン
14年2月17日月曜日
Example(Groovy)MetaProgramming, Closure
person.is {
name ‘taro’
age ’28’
}.say()
14年2月17日月曜日
def getPerson() { return new Person()}class Person{ ...}
person.is {
name ‘taro’
age ’28’
}.say()
personが定義されていない場合、
personのgetterが呼び出される ※生成型
14年2月17日月曜日
def getPerson() { ... }class Person{ ... def is(Closure closure){ closure.delegate = this closure() return this } ...}
person.is {
name ‘taro’
age ’28’
}.say()
isメソッドは自分で定義する ※埋め込み型
14年2月17日月曜日
def getPerson() { ... }class Person{ ... def is(Closure closure){ closure.delegate = this closure() return this } ...}
person.is {
name ‘taro’
age ’28’
}.say()
14年2月17日月曜日
def getPerson() { ... }class Person{ ... def is(Closure closure){ closure.delegate = this closure() return this } ...}
closureの属するインスタンスを設定する※thisを設定する前はScript1$_run_closure1クラス
person.is {
name ‘taro’
age ’28’
}.say()
14年2月17日月曜日
def getPerson() { ... }class Person{ ... def is(Closure closure){ closure.delegate = this closure() return this } ...}
person.is {
name ‘taro’
age ’28’
}.say()
closureを実行する
14年2月17日月曜日
def getPerson() { ... }person.is {
name ‘taro’
age ’28’
}.say()
class Person{ def Person(){ def mc = new ExpandoMetaClass(Person, false, true) mc.initialize() this.metaClass = mc } def methodMissing(String name, args){ this.metaClass.”${name}” = args[0] } ...}
Personクラスに - name(String) - age(String) は存在しない
14年2月17日月曜日
def getPerson() { ... }person.is {
name ‘taro’
age ’28’
}.say()
class Person{ def Person(){ def mc = new ExpandoMetaClass(Person, false, true) mc.initialize() this.metaClass = mc } def methodMissing(String name, args){ this.metaClass.”${name}” = args[0] } ...}
Personクラスに - name(String) - age(String) は存在しない
メソッド名 引数
14年2月17日月曜日
def getPerson() { ... }person.is {
name ‘taro’
age ’28’
}.say()
class Person{ def Person(){ def mc = new ExpandoMetaClass(Person, false, true) mc.initialize() this.metaClass = mc } def methodMissing(String name, args){ this.metaClass.”${name}” = args[0] } ...}
メソッド名 引数
メソッド名のプロパティを新規に作成※コンストラクタ内の記述が無いとエラー
14年2月17日月曜日
def getPerson() { ... }person.is {
name ‘taro’
age ’28’
}.say()
class Person{ def name = ‘taro’ def age = ’28’ ... def say(){ println “I’m ${this.name}. ${this.age} old.” }}
14年2月17日月曜日
def dsl = ‘’’person.is {
name ‘taro’age ’28’
}.say()‘’’
def dsl_support = ‘’’def getPerson{ ... }class Person{ ... }‘’’
def script = “””${dsl}${dsl_support}“””
new GroovyShell().evaluate(script)
https://gist.github.com/kaakaa/8599348
14年2月17日月曜日
Example(Ruby)Mixin
classA#hoge
moduleB#hoge moduleC#hoge
classA’#hoge
14年2月17日月曜日
Example(Ruby)
Pluggable Application by Mixin
https://github.com/kaakaa/PluggableMixinSample_Ruby
14年2月17日月曜日
内部DSLまとめ
DSLとしては微妙な出来…
黒魔術満載
実装を遅らせるテクニックは使えそうGroovy - Metaprogramming
Ruby - Mixin
14年2月17日月曜日
外部 DSL・ 独立した言語として開発される・ 独立DSL
14年2月17日月曜日
内部DSL vs 外部DSL
Groovyスクリプトとして解釈される
person.is {
name ‘taro’
age ’28’
}.say()
各文字の解釈を自分で決定する
14年2月17日月曜日
AST = Abstract Semantic Tree= 抽象構文木
14年2月17日月曜日
外部DSL
DSLの解釈に必要なパーツ
Lexer (字句解析器)Parser (構文解析器)Logic (処理ロジック) ParserGeneratorで
生成する
14年2月17日月曜日
14年2月17日月曜日
様々なParserの種類Top-Down Parser
ex) ANTLR ( Java / C / C++ / Python / Ruby)
XText (Eclipse)
Bottom-up Parser
ex) Yacc/Lex (C)
BIson/Flex (C++) 詳しくは...
第7章 外部DSLの実装
14年2月17日月曜日
外部DSL関連のツール
AST Browser
XText
Parser Generator
Gradle Antlr Plugin
Antlr2.7対応なので微妙(最新はAntlr4)
14年2月17日月曜日
AST BrowserGroovyConsoleからGroovyのASTを見れる (GroovyはAntlrで処理されている)
14年2月17日月曜日
XTextEclipse Plugin
http://www.eclipse.org/Xtext/
14年2月17日月曜日
XText構文の定義をグラフィカルに閲覧できるViewもある
自作DSLの補完などが可能なEditorも生成できる
14年2月17日月曜日
Parser Combinator
文法規則を関数抽象として実装する
Scala / Haskell / Newspeak
関数合成により文法規則を拡張できる
詳しくは...
第8章 Scalaのパーサーコンビネーター を使った外部DSLの設計
14年2月17日月曜日
外部DSLまとめ
より人間に近いDSLが構築可能
でも、めんどいわ…
14年2月17日月曜日
総括
DSL!!
開発者だけだよね!
テキストベ|スの
UIで喜ぶのは
14年2月17日月曜日
感想
DSL抜きにしても、プログラミングの概念・テクニックの勉強になる
Groovy / Ruby / Closure / Scalaなど、JVM上で実行可能な様々な言語が紹介されているのでJVM上で生きる人は読むべきな気が
14年2月17日月曜日
書籍について
付録A・Bに概念的なものが紹介されてるので、この本買うような人はとりあえずそこを読んでみる宜し
Groovy/Rubyで簡単に説明して、最後にScala
の良さをひけらかすスタイル
14年2月17日月曜日
Next!
Java?
Scala?
Chrome OS / Firefox OS ?
14年2月17日月曜日
終
14年2月17日月曜日