実践プログラミング DSL

Preview:

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日月曜日

内部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日月曜日

Recommended