Elmのさわれる副作用

 Elmのさわれる副作用

M3 tech meetup! #2 ~フロントエンドの副作用~ にて
http://m3-engineer.connpass.com/event/33802/

Dc32f175bec875eed2147b404f9bdc5a?s=128

Yosuke Torii

July 14, 2016
Tweet

Transcript

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

  2. ・鳥居 陽介 ・株式会社ワークスアプリケーションズ勤務 ・ CodeZine に 6 記事 (React.js, HTTP/2, Elm,

    BLE) ・ジンジャー研究室 誰? @jinjor
  3. Elm の紹介

  4. main = span [class "message"] [text "Hello, World!"] ・関数型言語 ・静的型付き言語

    ・ JavaScript にコンパイルされる ・ 2012 年誕生 Elm is 何?
  5. Elm = 言語 + フレームワーク ・ Virtual DOM 採用 ・

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

    Redux を生み出すきっかけになった  「 Elm Architecture 」 ・ http://guide.elm-lang.org/ React.js/Flux を追っている人なら Elm を楽しめるはず!
  7. 副作用の話

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

  9. 関数型言語としての位置づけ JavaScript Ruby Python TypeScript Java Scala Haskell Elm F#

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

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

    OCaml C# 副作用を 厳密に を扱う Flow
  12. どういうことか

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

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

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

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

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

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

    sendLogToServer('Hey'); clearLocalStorage(); fireMissiles(); return a + b; }
  19. 関数の型情報から 副作用の有無は分からない

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

    disableSend: true, inputField: “” }); }
  21. Elm で副作用を扱う方法 submit : State -> (State, Cmd Msg) submit

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

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

    { state | inputField = “” , disableSend = True } , send state.inputField )
  24. -- 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 )
  25. あえて返さないでみる submit : State -> State submit model = let

    unused = send model.inputField in { model | inputField = “” , disableSend = True }
  26. しかし なにも おこらなかった!

  27. Cmd そのものは副作用ではない Elm ランタイムに Cmd を返すと 副作用を起こせる Cmd Msg update

    : Msg → Model → (Model, Cmd Msg)
  28. おいしいところ

  29. 1.副作用の発見

  30. 副作用を起こす関数はどれ? parse(s: string): AST format(s: string): string update(model: Model, action:

    Action): Model register(model: Model, user: User): Model makeURL(model: Model): string
  31. parse : String → AST format : String → String

    update : Model → Action → Model register : Model → User → Model makeURL : Model → (String, Cmd Msg) 副作用を起こす関数はどれ?
  32. 2.副作用の禁止・許可

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

  34. 設計上、副作用を禁止したい 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);
  35. しかし、保証はできない 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
  36. Elm なら型で拘束できる update : Msg → Model → (Model, Cmd

    Msg) view : Model → Html Msg update 関数では副作用を起こせる view 関数では絶対に副作用を起こせない
  37. まとめ

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

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

  40. ありがとうございました