実践プログラミング

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を区別する...
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(...
内部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が定義されていない場合、
p...
person.is {
name ‘taro’

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

age ’28’

def is(Closure closure){
closure.delegate = ...
person.is {
name ‘taro’

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

age ’28’

def is(Closure closure){
closure.delegate = ...
person.is {
name ‘taro’

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

age ’28’

def is(Closure closure){
closure.delegate = ...
person.is {
name ‘taro’

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

age ’28’

def is(Closure closure){
closure.delegate = ...
person.is {
name ‘taro’

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

age ’28’

def mc =
new ExpandoMetaClass(Pers...
person.is {
name ‘taro’

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

age ’28’

def mc =
new ExpandoMetaClass(Pers...
person.is {
name ‘taro’

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

age ’28’

def mc =
new ExpandoMetaClass(Pers...
person.is {
name ‘taro’

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

age ’28’

def age = ’28’
...

}.say()

d...
def dsl = ‘’’
person.is {
name ‘taro’
age ’28’
}.say()
‘’’

def dsl_support = ‘’’
def getPerson{ ... }
class Person{ ... }...
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...
外部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の設計...
外部DSLまとめ

より人間に近いDSLが構築可能
でも、めんどいわ…

14年2月17日月曜日
総括
開
発
者
だ
け
だ
よ
ね
!

14年2月17日月曜日

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

D
S
L
!!
感想
DSL抜きにしても、プログラミングの概念・
テクニックの勉強になる
Groovy / Ruby / Closure / Scalaなど、JVM上
で実行可能な様々な言語が紹介されているの
でJVM上で生きる人は読むべきな気が

14年2月...
書籍について
付録A・Bに概念的なものが紹介されてるの
で、この本買うような人はとりあえずそこを
読んでみる宜し
Groovy/Rubyで簡単に説明して、最後にScala
の良さをひけらかすスタイル

14年2月17日月曜日
Next!
Java?
Scala?
Chrome OS / Firefox OS ?

14年2月17日月曜日
終
14年2月17日月曜日
Upcoming SlideShare
Loading in …5
×

実践プログラミング DSL

1,601 views

Published on

Published in: Technology

実践プログラミング DSL

  1. 1. 実践プログラミング DSL Domain-Specific Language 14年2月17日月曜日
  2. 2. Manning社の「∼in Action」シリーズは 色んなジャンル出てて良い感じですよ 14年2月17日月曜日
  3. 3. What Is DSL? 14年2月17日月曜日
  4. 4. What Is DSL? DSL = Domain Specific Language     ドメイン特化言語 14年2月17日月曜日
  5. 5. What Is DSL? Problem Domain 14年2月17日月曜日 Solution Domain
  6. 6. What Is DSL? Problem Domain 14年2月17日月曜日 Solution Domain
  7. 7. What Is DSL? Problem Domain 14年2月17日月曜日 Solution Domain
  8. 8. What Is DSL? DSLは単なるAPIの集合ではない。これらのAPIはいずれも簡 潔で、ドメインの語彙を用いている。 2009年のDSL開発者カンファレンスの基調講演においてファ ウラーは、他の汎用プログラミング言語とDSLを区別するも のは「限定された表現力」だと話している DSLスクリプトは下位に存在する実装を抽象化する 14年2月17日月曜日
  9. 9. I think DSL is ... (開発者でなく)ユーザーよりのコンパイラ? 14年2月17日月曜日
  10. 10. Implement DSL 14年2月17日月曜日
  11. 11. 内部DSL ・ 既存のホスト言語の上に実装されている ・ 埋め込みDSL 外部DSL ・ 独立した言語として開発される ・ 独立DSL 非テキストベースのDSL 14年2月17日月曜日
  12. 12. 内部DSL 外部DSL 非テキストベースのDSL 14年2月17日月曜日
  13. 13. 内部 DSL ・ 既存のホスト言語の上に実装されている ・ 埋め込みDSL 14年2月17日月曜日
  14. 14. Example(Java) Smart API (Fluent Interface) Person person = new Person(); person.setName(“taro”) .setAge(28) .build() .say(); Is this smart...? 14年2月17日月曜日
  15. 15. 内部DSLの実装パターン 14年2月17日月曜日
  16. 16. Example(Groovy) MetaProgramming, Closure person.is { name ‘taro’ age ’28’ }.say() 14年2月17日月曜日
  17. 17. person.is { def getPerson() { return new Person() name ‘taro’ } age ’28’ class Person{ }.say() personが定義されていない場合、 personのgetterが呼び出される ※生成型 14年2月17日月曜日 ... }
  18. 18. 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日月曜日 }
  19. 19. person.is { name ‘taro’ def getPerson() { ... } class Person{ ... age ’28’ def is(Closure closure){ closure.delegate = this }.say() closure() return this } ... } 14年2月17日月曜日
  20. 20. 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日月曜日
  21. 21. 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日月曜日
  22. 22. 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日月曜日 } ... }
  23. 23. 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日月曜日 } ... } 引数
  24. 24. 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日月曜日
  25. 25. 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日月曜日
  26. 26. 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日月曜日
  27. 27. Example(Ruby) Mixin classA#hoge classA’#hoge moduleB#hoge 14年2月17日月曜日 moduleC#hoge
  28. 28. Example(Ruby) Pluggable Application by Mixin https://github.com/kaakaa/ PluggableMixinSample_Ruby 14年2月17日月曜日
  29. 29. 内部DSLまとめ DSLとしては微妙な出来… 黒魔術満載 実装を遅らせるテクニックは使えそう Groovy - Metaprogramming Ruby - Mixin 14年2月17日月曜日
  30. 30. 外部 DSL ・ 独立した言語として開発される ・ 独立DSL 14年2月17日月曜日
  31. 31. 内部DSL vs 外部DSL Groovyスクリプトとして 解釈される person.is { name ‘taro’ age ’28’ }.say() 各文字の解釈を 自分で決定する 14年2月17日月曜日
  32. 32. AST = Abstract Semantic Tree = 抽象構文木 14年2月17日月曜日
  33. 33. 外部DSL DSLの解釈に必要なパーツ Lexer (字句解析器) Parser (構文解析器) Logic (処理ロジック) ParserGeneratorで 生成する 14年2月17日月曜日
  34. 34. 14年2月17日月曜日
  35. 35. 様々な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日月曜日
  36. 36. 外部DSL関連のツール AST Browser XText Parser Generator Gradle Antlr Plugin Antlr2.7対応なので微妙(最新はAntlr4) 14年2月17日月曜日
  37. 37. AST Browser GroovyConsoleからGroovyのASTを見れる  (GroovyはAntlrで処理されている) 14年2月17日月曜日
  38. 38. XText http://www.eclipse.org/Xtext/ Eclipse Plugin 14年2月17日月曜日
  39. 39. XText 構文の定義をグラフィカルに閲覧できるViewもある 自作DSLの補完などが可能なEditorも生成できる 14年2月17日月曜日
  40. 40. Parser Combinator 文法規則を関数抽象として実装する Scala / Haskell / Newspeak 関数合成により文法規則を拡張できる 詳しくは... 第8章 Scalaのパーサーコンビネーター を使った外部DSLの設計 14年2月17日月曜日
  41. 41. 外部DSLまとめ より人間に近いDSLが構築可能 でも、めんどいわ… 14年2月17日月曜日
  42. 42. 総括 開 発 者 だ け だ よ ね ! 14年2月17日月曜日 Uテ I キ でス 喜ト ぶベ の ¦ はス の D S L !!
  43. 43. 感想 DSL抜きにしても、プログラミングの概念・ テクニックの勉強になる Groovy / Ruby / Closure / Scalaなど、JVM上 で実行可能な様々な言語が紹介されているの でJVM上で生きる人は読むべきな気が 14年2月17日月曜日
  44. 44. 書籍について 付録A・Bに概念的なものが紹介されてるの で、この本買うような人はとりあえずそこを 読んでみる宜し Groovy/Rubyで簡単に説明して、最後にScala の良さをひけらかすスタイル 14年2月17日月曜日
  45. 45. Next! Java? Scala? Chrome OS / Firefox OS ? 14年2月17日月曜日
  46. 46. 終 14年2月17日月曜日

×