Slide 1

Slide 1 text

Elm のさわれる副作用 2016/07/14 Yosuke Torii

Slide 2

Slide 2 text

・鳥居 陽介 ・株式会社ワークスアプリケーションズ勤務 ・ CodeZine に 6 記事 (React.js, HTTP/2, Elm, BLE) ・ジンジャー研究室 誰? @jinjor

Slide 3

Slide 3 text

Elm の紹介

Slide 4

Slide 4 text

main = span [class "message"] [text "Hello, World!"] ・関数型言語 ・静的型付き言語 ・ JavaScript にコンパイルされる ・ 2012 年誕生 Elm is 何?

Slide 5

Slide 5 text

Elm = 言語 + フレームワーク ・ Virtual DOM 採用 ・ Redux を生み出すきっかけになった  「 Elm Architecture 」 ・ http://guide.elm-lang.org/

Slide 6

Slide 6 text

Elm = 言語 + フレームワーク ・ Virtual DOM 採用 ・ Redux を生み出すきっかけになった  「 Elm Architecture 」 ・ http://guide.elm-lang.org/ React.js/Flux を追っている人なら Elm を楽しめるはず!

Slide 7

Slide 7 text

副作用の話

Slide 8

Slide 8 text

Elm は副作用を 厳密に扱う言語

Slide 9

Slide 9 text

関数型言語としての位置づけ JavaScript Ruby Python TypeScript Java Scala Haskell Elm F# OCaml C# 型の強さ Flow

Slide 10

Slide 10 text

関数型言語としての位置づけ JavaScript Ruby Python TypeScript Java Scala Haskell Elm F# OCaml C# 型の強さ Flow

Slide 11

Slide 11 text

関数型言語としての位置づけ JavaScript Ruby Python TypeScript Java Scala Haskell Elm F# OCaml C# 副作用を 厳密に を扱う Flow

Slide 12

Slide 12 text

どういうことか

Slide 13

Slide 13 text

Flow で型をつけてみる function add(a, b) { return a + b; }

Slide 14

Slide 14 text

add() は number を返す関数 function add(a, b): number { return a + b; }

Slide 15

Slide 15 text

add() は number を返す関数 function add(a, b): number { callCount++; return a + b; }

Slide 16

Slide 16 text

add() は number を返す関数 function add(a, b): number { callCount++; sendLogToServer('Hey'); return a + b; }

Slide 17

Slide 17 text

add() は number を返す関数 function add(a, b): number { callCount++; sendLogToServer('Hey'); clearLocalStorage(); return a + b; }

Slide 18

Slide 18 text

add() は number を返す関数 function add(a, b): number { callCount++; sendLogToServer('Hey'); clearLocalStorage(); fireMissiles(); return a + b; }

Slide 19

Slide 19 text

関数の型情報から 副作用の有無は分からない

Slide 20

Slide 20 text

もう少し現実的な例 function submit(state): State { send(state.inputField); return Object.assign({}, state, { disableSend: true, inputField: “” }); }

Slide 21

Slide 21 text

Elm で副作用を扱う方法 submit : State -> (State, Cmd Msg) submit state = ( { state | inputField = “” , disableSend = True } , send state.inputField )

Slide 22

Slide 22 text

Elm で副作用を扱う方法 submit : State -> (State, Cmd Msg) submit state = ( { state | inputField = “” , disableSend = True } , send state.inputField )

Slide 23

Slide 23 text

型に書いていないことをすると… submit : State -> State submit state = ( { state | inputField = “” , disableSend = True } , send state.inputField )

Slide 24

Slide 24 text

-- TYPE MISMATCH ----------------------------------------------- The type annotation for `update` does not match its definition. 50| update : Msg -> Model -> Model ^^^^^^^^^^^^^^^^^^^^^ The type annotation is saying: Msg -> Model -> { disableSend : Bool, inputField : String } But I am inferring that the definition has this type: Msg -> Model -> ( Model, Cmd a )

Slide 25

Slide 25 text

あえて返さないでみる submit : State -> State submit model = let unused = send model.inputField in { model | inputField = “” , disableSend = True }

Slide 26

Slide 26 text

しかし なにも おこらなかった!

Slide 27

Slide 27 text

Cmd そのものは副作用ではない Elm ランタイムに Cmd を返すと 副作用を起こせる Cmd Msg update : Msg → Model → (Model, Cmd Msg)

Slide 28

Slide 28 text

おいしいところ

Slide 29

Slide 29 text

1.副作用の発見

Slide 30

Slide 30 text

副作用を起こす関数はどれ? parse(s: string): AST format(s: string): string update(model: Model, action: Action): Model register(model: Model, user: User): Model makeURL(model: Model): string

Slide 31

Slide 31 text

parse : String → AST format : String → String update : Model → Action → Model register : Model → User → Model makeURL : Model → (String, Cmd Msg) 副作用を起こす関数はどれ?

Slide 32

Slide 32 text

2.副作用の禁止・許可

Slide 33

Slide 33 text

設計上、副作用を禁止したい var newState = reduce(oldState, action);

Slide 34

Slide 34 text

設計上、副作用を禁止したい http://redux.js.org/docs/basics/Reducers.html ”Given the same arguments, it should calculate the next state and return it. No surprises. No side effects. No API calls. No mutations. Just a calculation.” var newState = reduce(oldState, action);

Slide 35

Slide 35 text

しかし、保証はできない var newState = reduce(oldState, action); ”Given the same arguments, it should calculate the next state and return it. No surprises. No side effects. No API calls. No mutations. Just a calculation.” http://redux.js.org/docs/basics/Reducers.html

Slide 36

Slide 36 text

Elm なら型で拘束できる update : Msg → Model → (Model, Cmd Msg) view : Model → Html Msg update 関数では副作用を起こせる view 関数では絶対に副作用を起こせない

Slide 37

Slide 37 text

まとめ

Slide 38

Slide 38 text

副作用を可視化すると メリットが沢山ある!

Slide 39

Slide 39 text

Elm で快適 Frontend Life を満喫しよう

Slide 40

Slide 40 text

ありがとうございました