狠狠撸

狠狠撸Share a Scribd company logo
実践プログラミング

DSL

Domain-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日月曜日
What Is DSL?
Problem Domain

14年2月17日月曜日

Solution Domain
What Is DSL?
Problem Domain

14年2月17日月曜日

Solution Domain
What Is DSL?
Problem Domain

14年2月17日月曜日

Solution Domain
What Is DSL?
DSLは単なるAPIの集合ではない。これらのAPIはいずれも簡
潔で、ドメインの語彙を用いている。

2009年のDSL開発者カンファレンスの基調講演においてファ
ウラーは、他の汎用プログラミング言語とDSLを区別するも
のは「限定された表現力」だと話している

DSLスクリプトは下位に存在する実装を抽象化する

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日月曜日
person.is {

def getPerson() {
return new Person()

name ‘taro’

}

age ’28’

class Person{

}.say()

personが定義されていない場合、
personのgetterが呼び出される?※生成型

14年2月17日月曜日

...
}
person.is {
name ‘taro’

def getPerson() { ... }
class Person{
...

age ’28’

def is(Closure closure){
closure.delegate = this

}.say()

closure()
return this
}
...

isメソッドは自分で定義する?※埋め込み型

14年2月17日月曜日

}
person.is {
name ‘taro’

def getPerson() { ... }
class Person{
...

age ’28’

def is(Closure closure){
closure.delegate = this

}.say()

closure()
return this
}
...
}

14年2月17日月曜日
person.is {
name ‘taro’

def getPerson() { ... }
class Person{
...

age ’28’

def is(Closure closure){
closure.delegate = this

}.say()

closure()
return this
}
...
}

closureの属するインスタンスを設定する
※thisを設定する前はScript1$_run_closure1クラス

14年2月17日月曜日
person.is {
name ‘taro’

def getPerson() { ... }
class Person{
...

age ’28’

def is(Closure closure){
closure.delegate = this

}.say()

closure()
return this
}
...
}

closureを実行する

14年2月17日月曜日
person.is {
name ‘taro’

def getPerson() { ... }
class Person{
def Person(){

age ’28’

def mc =
new ExpandoMetaClass(Person, false, true)

}.say()

mc.initialize()
this.metaClass = mc
}

Personクラスに

def methodMissing(String name, args){
this.metaClass.”${name}” = args[0]

- name(String)
- age(String)?
は存在しない

14年2月17日月曜日

}
...
}
person.is {
name ‘taro’

def getPerson() { ... }
class Person{
def Person(){

age ’28’

def mc =
new ExpandoMetaClass(Person, false, true)

}.say()

mc.initialize()
this.metaClass = mc

メソッド名

}

Personクラスに

def methodMissing(String name, args){
this.metaClass.”${name}” = args[0]

- name(String)
- age(String)?
は存在しない

14年2月17日月曜日

}
...
}

引数
person.is {
name ‘taro’

def getPerson() { ... }
class Person{
def Person(){

age ’28’

def mc =
new ExpandoMetaClass(Person, false, true)

}.say()

mc.initialize()
this.metaClass = mc

メソッド名

引数

}
def methodMissing(String name, args){
this.metaClass.”${name}” = args[0]
}
...
}

メソッド名のプロパティを新規に作成
※コンストラクタ内の記述が無いとエラー

14年2月17日月曜日
person.is {
name ‘taro’

def getPerson() { ... }
class Person{
def name = ‘taro’

age ’28’

def age = ’28’
...

}.say()

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
classA’#hoge
moduleB#hoge

14年2月17日月曜日

moduleC#hoge
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 Browser
GroovyConsoleからGroovyのASTを見れる?
(GroovyはAntlrで処理されている)

14年2月17日月曜日
XText

http://www.eclipse.org/Xtext/

Eclipse Plugin

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日月曜日
総括
開
発
者
だ
け
だ
よ
ね
!

14年2月17日月曜日

Uテ
I キ
でス
喜ト
ぶベ
の ?
はス
の

D
S
L
!!
感想
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日月曜日

More Related Content

実践プログラミング DSL