Your SlideShare is downloading. ×
  • Like
Javascript as an Embedded DSL - Expression Problemの解法例
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Javascript as an Embedded DSL - Expression Problemの解法例

  • 1,583 views
Published

LMS(Lightweght Modular Staging)を応用したScala→Javascriptの変換の論文を題材に、Traitを駆使したモジュール分割と合成の例を説明した資料です。

LMS(Lightweght Modular Staging)を応用したScala→Javascriptの変換の論文を題材に、Traitを駆使したモジュール分割と合成の例を説明した資料です。

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,583
On SlideShare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
10
Comments
0
Likes
4

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 「Javascript as an Embedded DSL」を 読んで - ScalaにおけるExpression Problemの解法 - Scala基礎勉強会  2012/10/21 前⽥田  康⾏行行  (@maeda_̲)
  • 2. 自己紹介 ¨  前⽥田康⾏行行  (@maeda_̲  ) ¨  名古屋在住のフリーランス http://www.illi-‐‑‒ichi.com ¨  好きな⾔言語 ¤  Scala ¤  Smalltalk ¨  DyNagoya  (Dynamic  language  +  Nagoya) ¤  http://dynagoya.info   ¤  @dynagoya_̲info
  • 3. 注意 (2014/6/27 追記) 最近話題のScala.jsと 本資料料で扱うjs-‐‑‒scalaは別物で、 全く異異なるアプローチです。
  • 4. JavaScript as an Embedded DSL ¨  authors ¤  Grzegorz  Kossakowski,  Nada  Amin,  Tiark   Rompf,  and  Martin  Odersky ¨  published ¤  ECOOP  2012  –  Object-‐‑‒Oriented   Programming,  vol.  7313,  p.  409-‐‑‒434   ¨  abstract ¤  Javascriptを出⼒力力するScalaの内部DSLを作った。 ¤  「Lightweight  Modular  Staging」の応⽤用
  • 5. Multi-Staging Programming(MSP) ¨  段階に分けてコードを変換 ¤  例例: 記述性の⾼高いコード  →  効率率率のよいコードに変換  →  実⾏行行 ¨  コード⽣生成時をStaging,  ⽣生成後をStagedという ¨  MSPの例例 ¤  O.  Kiselyov,  K.  N.  Swadi,  and  W.  Taha.  A   methodology  for  generating  verified  combinatorial   circuits.  In  G.  C.  Buttazzo,  editor,  EMSOFT,  pages   249–258.  ACM,  2004. ¤  MetaOcamlを使⽤用したFFT(⾼高速フーリエ変換)
  • 6. Lightweight Modular Staging(LMS) ¨  ScalaのMSPのための枠組み ¤  Lightweight n  ⾔言語拡張ではなく、ライブラリで実装 (類似研究ではMetaOcamlやTemplate  Haskellを使⽤用) ¤  Modular n  好きな部品を好きなように追加・取り替え可能 ¤  Staging ¨  LMSの応⽤用例例 ¤  Delite(並列列計算)      http://stanford-‐‑‒ppl.github.com/Delite/ ¤  JS-‐‑‒Scala  (Scala  →  Javascript) https://github.com/js-‐‑‒scala/virtualization-‐‑‒lms-‐‑‒core
  • 7. Scala → Javascriptの利点 ¨  型安全 ¨  サーバーサイドとクライアントサイドの⾔言語 を統⼀一 ¨  限定継続によるcall  backの排除 ¨  ScalaにはObjectもあるし、型が不不要な場合は Dynamic  Traitも使えるので、JSとの親和性 は⾼高い ¨  DSLで使⽤用できる部品の追加および差し替え が容易易            →  Expression  Problemの解決が必須
  • 8. Expression Problem ¨  データ構造やその操作を追加した時に、下記 の条件すべてを満たせるか? ¤  Extensibility  in  both  dimensions (データ構造と操作の両⽅方の意) ¤  Strong  static  type  safety ¤  No  modification  or  duplication ¤  Separate  compilation ¤  Independent  extensibility(Scalaチームにより追加)
  • 9. Independent extensibility ¨  独⽴立立した拡張は組み合わせて使⽤用することが できること Matthias  Zenger,  Martin  Odersky,   Independently  Extensible  Solutions  to  the  Expression   Problem,  I&C  Technical  Report  No.  200433,  March  2004.
  • 10. 主役はTrait ¨  それぞれの拡張をTraitにして分割 ¨  JS  traitはDSL内で何が使えるかの定義をまと めたもの ¨  ノードの種類ごとにtraitが分割されている。 trait  JS  extends  LiftNumeric  with  NumericOps  with   OrderingOps  with  Equal  with  IfThenElse  with   While  with  LiftBoolean  with  BooleanOps  with   LiftString  with  StringOps  with  DynamicBase  with   Arrays  with  Variables  with  JSFunctions  with   JSLiteral
  • 11. 構文木のノードを変換 構文木→JS 構文木のノードを変換 構文木→JS Generator Scala → JS 全体像 DSLの記述 DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) Javascript Generator mix in implement mix in mix in DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) 部品の実装 (DSL→構文木) DSL内で使える部品 (定義のみ) 構文木のノードを変換 構文木→JS mix in Trait Instance correspond
  • 12. JS-Scalaでの拡張の例 ¨  以降降はjQueryのための部品を追加する場合を 考える ¨  下記のそれぞれのTraitを作成する ¤  DSL内でjQueryを使うAPI定義 ¤  DSL上のjQueryを構⽂文⽊木上のノードへ変換 ¤  ノードからJSへの出⼒力力⽅方法の実装 ¨  既存の機能と独⽴立立して、この機能の追加をす る
  • 13. 構文木のノードを変換 構文木→JS 構文木のノードを変換 構文木→JS Generator Scala → JS 全体像 DSLの記述 DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) Javascript Generator mix in implement mix in mix in DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) 部品の実装 (DSL→構文木) DSL内で使える部品 (定義のみ) 構文木のノードを変換 構文木→JS mix in Trait Instance correspond
  • 14. DSLを書く ¨  Rep[T]型の値はJSレベルでT型に評価されるノードを表す //  DSLの記述 trait  SomeDSL  {  this:  JQuery  with  JS  =>    def  code  =  $(“#message”).html(“Hello  World”) } //  DSLで使⽤用可能な部品の定義 trait  JQuery  extends  JSProxyBase  {    def  $(selector:  Rep[String]):  Rep[JQElement]        trait  JQElement{        def  html(html:  Rep[String]):  Rep[JQElement]    }    implicit  def  repToJQuery(x:  Rep[JQElement]):  JQElement  =          repProxy[JQElement](x) }
  • 15. 構文木のノードを変換 構文木→JS 構文木のノードを変換 構文木→JS Generator Scala → JS 全体像 DSLの記述 DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) Javascript Generator mix in implement mix in mix in DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) 部品の実装 (DSL→構文木) DSL内で使える部品 (定義のみ) 構文木のノードを変換 構文木→JS mix in Trait Instance correspond
  • 16. DSLに実装を与える(1) //  DSLの表現から構⽂文⽊木のノードへの変換⽅方法の定義 trait  JQueryExp  extends  JQuery  with  JSProxyExp  {    case  class  JQ(selector:  Exp[String])  extends  Def[JQElement]          def  $(selector:  Exp[String]):  Exp[JQElement]  =              reflectEffect(JQ(selector)) } ¨  DSLレベルではRep[T]、実装レベルではExp[T]型を使⽤用す る ¨  Staging時にreflectEffectがインスタンス変数へノードの登 録して、構⽂文⽊木を組み⽴立立てる ¨  JQElementについての実装はJSProxyExpがリフレクション で良良きにやってくれる
  • 17. DSLに実装を与える(2) //  新しいノードが不不要な場合の例例 trait  SleepExp  extends  JSLibExp  with  JSFunctionsExp  {    def  sleep(delay:  Exp[Int])  =  shift  {          k:  (Exp[Unit]  =>  Exp[Unit])  =>            window.setTimeout(fun(k),  delay)    } } ¨  既存の種類のノードに置き換えることも可能 ¨  この例例では、setTimeoutのCallbackとして継続を渡す ように構⽂文⽊木を組み⽴立立てる。 (fun  :  Exp[A]  =>  Exp[B]  =>  Exp[A  =>  B]) ¨  他にも定数畳み込みなどの最適化なども可能
  • 18. 構文木のノードを変換 構文木→JS 構文木のノードを変換 構文木→JS Generator Scala → JS 全体像 DSLの記述 DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) Javascript Generator mix in implement mix in mix in DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) 部品の実装 (DSL→構文木) DSL内で使える部品 (定義のみ) 構文木のノードを変換 構文木→JS mix in Trait Instance correspond
  • 19. JSのコードへ変換 ¨  abstract  valueのIRがTrait合成時に提供されるべき、 ノードを指定している  (IR  =  Intermediate  Representation) ¨  担当のノードの変換をする。それ以外は親Traitにお任せ //  JQueryのノードをJSのコードへ変換 trait  GenJQuery  extends  JSGenProxy  with  JSGenLib{    val  IR:  JQueryExp                  //  abstract  value      import  IR._̲    override  def  emitNode(sym:  Sym[Any],  rhs:  Def[Any])(        implicit  stream:  PrintWriter)  =  rhs  match  {            case  JQ(s)  =>  emitValDef(sym,  "$("  +  quote(s)  +  ")")            case  _̲  =>  super.emitNode(sym,  rhs)    } }
  • 20. 構文木のノードを変換 構文木→JS 構文木のノードを変換 構文木→JS Generator Scala → JS 全体像 DSLの記述 DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) Javascript Generator mix in implement mix in mix in DSL内で使える部品 (インターフェース) 部品の実装 (DSL→構文木) 部品の実装 (DSL→構文木) DSL内で使える部品 (定義のみ) 構文木のノードを変換 構文木→JS mix in Trait Instance correspond
  • 21. DSLをJSに変換 ¨  これまでのTraitを合成して、Generatorを作 る ¨  コード⽣生成⽤用のTraitが要求していたabstract   valueをこのような形で解決する。 ¨  必要なTraitを選んで、機能の拡張をすること ができる。 new  SomeDSL  with  JQueryExp  with  JSExp  {  self  =>      val  codegen  =  new  JQueryGen  with  JSGen  {              val  IR:  self.type  =  self      } }
  • 22. まとめ ¨  ScalaのTraitは強⼒力力 ¤  モジュールを細かく分割して、実装・テストが可能 ¤  任意の組み合わせで合成 ¤  self  type  annotationやabstract  type/valueなどの 制約により、不不整合はコンパイルエラー ¨  JS-‐‑‒Scalaのコードは、Cake  Patternや Expression  Problem解法の好例例 ¨  https://github.com/js-‐‑‒scala/js-‐‑‒scala
  • 23. LMS・JS-Scalaの感想 ¨  課題はJSレベルでのデバッグ ¤  MSP(Multi  Staging  Programming)の課題 ¤  ⽣生成されるコードが機械的な感じで読み難い ¨  このDSLは⾃自由に書けない ¤  提供された部品の範囲でのみ書ける ¤  できることを制限させるような使い⽅方 ¤  こんな構成↓がやりやすそう LMS 独自Parts 独自DSL ← 人海戦術 ← スキルフルな人が実装
  • 24. 参考文献 ¨  Lightweight  Modular  Staging:  A  Pragmatic   Approach  to  Runtime  Code  Generation  and   Compiled  DSLs by  Tiark  Rompf  and  Martin  Odersky,  EPFL GPCE  2010,  Eindhoven,  The  Netherlands,   October  2010 ¨  A  Gentle  Introduction  to  Multi-‐‑‒stage   Programming by  Walid  Taha ¨  Matthias  Zenger,  Martin  Odersky,   Independently  Extensible  Solutions  to  the   Expression  Problem,  I&C  Technical  Report  No.   200433,  March  2004.