callback dsl on haxe
DESCRIPTION
Frontrend FukuokaでLTした資料ですTRANSCRIPT
![Page 1: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/1.jpg)
Callback DSL on Haxe
by Technical Rockstars CTO @nobkz
![Page 2: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/2.jpg)
自己紹介
Technical Rockstars CTO
tw : @nobkz
Haxe/JS/C#/Java/Objective-C++
好きな言語:Lisp(Common Lisp, Gauche)/Haskell/OCaml/Prolog
福岡Haxe勉強会主催
![Page 3: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/3.jpg)
Haxe?
![Page 4: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/4.jpg)
Haxe
いろんな言語にコンパイルできる (to Flash, C++, C#, JS, PHP, Java, NekoVM)
強力な型システム(型推論など)
強力なマクロ
![Page 5: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/5.jpg)
-@nobkz
“これから
HaxeでDSL作った話しをします”
![Page 6: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/6.jpg)
なぜHaxeでDSLを 実装したか?
![Page 7: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/7.jpg)
-@nobkz
“ある日のことでした”
![Page 8: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/8.jpg)
–@nobkz
“それはHaxeでnodeとか
seleniumのテストを書いていました。”
![Page 9: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/9.jpg)
@nobkz
そいつは、いつのまにか
ぶくぶくと大きくなってました。
![Page 10: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/10.jpg)
コールバック地獄例
![Page 11: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/11.jpg)
僕はコールバック地獄に 悩まされていました
![Page 12: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/12.jpg)
ある日のこと…
![Page 13: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/13.jpg)
僕は最高の3大エンタメ (まどまぎ、ボルテ、Scheme)の一つ、
Schemeを楽しんでいた。
![Page 14: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/14.jpg)
–@nobkz
“ん?コールバックて CPSスタイルだよね….”
![Page 15: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/15.jpg)
CPSスタイル(Scheme)
![Page 16: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/16.jpg)
–@nobkz
“そういえばHaskellに継続モナド ってあったよなぁ。”
![Page 17: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/17.jpg)
http://www.sampou.org/haskell/a-a-monads/html/contmonad.html
![Page 18: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/18.jpg)
そして僕は気づいた
![Page 19: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/19.jpg)
–@nobkz
“そうだ! 継続モナドを同様の仕組みで
DSLを創れば良いんだ!”
![Page 20: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/20.jpg)
継続モナドの利用
コールバック地獄 -> CPSスタイルに似ている?
コールバックを継続モナドで表現する
それを、合成すれば良いんじゃないか?
![Page 21: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/21.jpg)
方針
1 . とりあえず、モナドの結合ができるようにする
2. do記法をつくる
3. コールバックDSLをつくる
![Page 22: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/22.jpg)
そしていろいろあって
![Page 23: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/23.jpg)
実装しました。 (この点については
次回のHaxe勉強会で話します)
![Page 24: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/24.jpg)
結局できたもの
![Page 25: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/25.jpg)
Before
![Page 26: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/26.jpg)
Before
![Page 27: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/27.jpg)
After
![Page 28: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/28.jpg)
After
![Page 29: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/29.jpg)
なんということでしょう!
![Page 30: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/30.jpg)
結果
簡単になった!
コールバックのネストが無くなった。
構文のノイズが無くなって読みやすい!
ただ、ボイラープレートが残っている感。
![Page 31: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/31.jpg)
けどちょっとだけ、 実装の仕組みについて
(時間が無ければ飛します)
![Page 32: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/32.jpg)
Monad?
![Page 33: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/33.jpg)
Monad
言語内DSLを構築するための仕組み
モジュールの組み合せ方
背景に数学的な理論がある(圏論)
![Page 34: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/34.jpg)
Optionモナド作成
![Page 35: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/35.jpg)
Option(Maybe)型について
Option(HaskellではMaybe)型をつくる
data Maybe a = Just a | Nothing
Haxeではenumで実現
![Page 36: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/36.jpg)
HaxeのEnumについて
enumはCの列挙体とはちょっとちがう
コンストラクタがパラメータを持つことができる
![Page 37: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/37.jpg)
enumの例
enum MyNumber{ Zero; Plus(i:Int); Minus(i:Int); } !var x : MyNumber = Zero; var y : MyNumber = Plus(10); var z : MyNumber = Minus(10);
![Page 38: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/38.jpg)
EnumでOptionの実装
型パラメータとEnumでOptionを作った。
enum OptionDef<T>{ None; // Nothing of Haskell Some(i:T); // Just of Haskell }
![Page 39: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/39.jpg)
returnとbind
モナドで必要に関数は2つ
Mが対象のデータ型だとする
return :: A -> M A
>>= :: M A -> (A -> M B) -> M B
これらの関数がモナド則を満すように実装する
![Page 40: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/40.jpg)
Haxeでのreturnとbind
クラスメソッドとして実装する
returnだと、返り値のreturnと混合するので、mPackとした。
>>=はmBindとした。
![Page 41: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/41.jpg)
Optionのreturnとbindの型定義
Option型のクラスをつくり、クラスメソッドとして実装する
Option.mPack<A> : A -> OptionDef<A>
Option.mBind<A,B> : OptionDef<A> -> ( A -> OptionDef<B> ) -> OptionDef<B>
![Page 42: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/42.jpg)
実装
class Option{ public static function mPack <A>(a : A) : Option<A> return Some(a); ! public static function mBind <A,B>(m : OptionDef<A>, f : A -> OptionDef<B>) : OptionDef<B> return switch(m){ case Some(a) : f(a); case None : None; }; }
![Page 43: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/43.jpg)
returnとbindを組み合わせ
モナドの計算はbind(>>=)とreturnで組織する
Haskell の例:return 10 >>= (\x -> return x >>= (\y -> return x >>= (\z -> return (z + x + y))))
![Page 44: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/44.jpg)
Haxeでのモナドの計算
Haxeのある機能をつかわないとやりづらい
Option.mBind(Option.mPack(10),function(x) return Option.mBind(Option.mPack(x), function(y) return Option.mBind(Option.mPack(y),function(z) return Option.mPack(x+y+z))));
しかるある機能を使うと途端に楽になる
![Page 45: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/45.jpg)
using!
using Option; !10.mPack().mBind(function(x) return x.mPack().mBind(function(y) return y.mPack().mBind(function(z) return (x + y + z).mPack())));
usingを使うと第一引数が、なんと、メソッドを呼び出すオブジェクトみたいに!
![Page 46: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/46.jpg)
HaxeでOptionモナドを実装した
とりあえず、Haxeでも十分にモナドの計算ができる!
次に継続モナドだが、次回Haxe勉強会で
![Page 47: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/47.jpg)
Haxeのdo記法の実装
![Page 48: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/48.jpg)
前提知識:Haxeのマクロ
Haxeのマクロ(黒魔法とも呼ばれる)は新しい構文を定義することができる
マクロでdo記法をつくる
![Page 49: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/49.jpg)
構文木はEnum
Haxeの構文木はEnumで表現されている。
1 + 1の構文木は次の様にHaxeで表わせる
![Page 50: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/50.jpg)
1 + 1の構文木
{ expr : EBinop(OpAdd, { expr : EConst(CInt(1)), pos : #pos(Sample.hx:10: characters 6-7) }, { expr : EConst(CInt(2)), pos : #pos(Sample.hx:10: characters 10-11) }), pos : #pos(example/Sample.hx:28: characters 6-11) }
![Page 51: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/51.jpg)
構文木を書き代える
Haxeのマクロは構文木を書き代えることができる
構文木を書き代えることによって、別の表現を与える事ができる
![Page 52: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/52.jpg)
例 : 1 + 1を引き算にする
macro public static function toSub(e){ return switch (e.expr) { case EBinop(OpAdd, a, b): macro $a - $b; case _: e; } } !!toSub(1 + 1); // => 0
![Page 53: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/53.jpg)
マクロでdo記法を実装
詳しくは次回Haxe勉強会で説明します
![Page 54: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/54.jpg)
これから先は次回Haxe勉強会にて!
![Page 55: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/55.jpg)
Haxe勉強会やんお!
2月のどっかやんお!
福岡でやんお!
詳細は、@nobkzで流れまう!
![Page 56: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/56.jpg)
Callback DSL &
Monad Frameworks のこれから
![Page 57: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/57.jpg)
これから
liftのなどのモナド関数に実装
読みやすいDSLを目指す
LinqみたいなDSLの実装
公開するお!
![Page 58: Callback DSL on Haxe](https://reader038.vdocuments.site/reader038/viewer/2022102705/54b1e6cf4a79595f7b8b45eb/html5/thumbnails/58.jpg)
ご清聴ありがとうございました! @nobkz