Let's learn Elm

Let's learn Elm

I had a talk about Elm-lang in our company. The main target is frontend engineer who is familiar to trendy MV* frameworks.

Dc32f175bec875eed2147b404f9bdc5a?s=128

Yosuke Torii

July 01, 2015
Tweet

Transcript

  1. Let's learn Elm! 2015/07/01 @Worksap ATE Yosuke Torii

  2. This slide is about... - What is Elm? - Why

    is Elm great? - For web-app developers × Type systems × Useful tools/libraries × For game developers × For FP developers
  3. What's Elm? - FRP(Functional Reactive Programming) - Haskell-like Syntax -

    No runtime errors - Compile to JavaScript main = span [class "welcome-message"] [text "Hello, World!"]
  4. a = 1 b = 1 c = a +

    b print c // => 2 Reactive Programming
  5. a = 1 b = 1 c = a +

    b print c // => 2 b = 2 print c // => ? Reactive Programming
  6. Reactive Programming a b c + 1 1 2

  7. Reactive Programming a b c + 1 2 3

  8. Reactive Programming a b c + 2 2 4

  9. a = model(1) b = model(1) updateC = function() {

    c = a.value + b.value } a.onChange(updateC) b.onChange(updateC) updateC() I know the observer pattern!
  10. Functional Reactive Programming 2 1 Time a Signal : function

    of time
  11. Functional Reactive Programming 2 1 2 1 Time Time a

    b
  12. Functional Reactive Programming 2 1 2 1 Time Time 4

    2 Time 3 1 a b c
  13. Basis of FRP 2 1 4 2 Time Time a

    b map
  14. Basis of FRP 3 1 Time Time a b filter

    4 2 4 2
  15. Basis of FRP 1 1 Time Time a b scan

    1 1 3 1 4 2
  16. Basis of FRP 1 1 Time Time a b merge

    2 2 Time c 1 1 2 2
  17. Basis of FRP 2 1 Time Time a b lift

    2 1 Time c 3 1 4 2
  18. FRP meets MV* architecture Action Model View <div>Hello, John Smith!</div>

    John Smith John Smith keydown keydown
  19. FRP meets MV* architecture MV* FP Elm AngularJS Backbone.js React.js

    Ember.js Haskell Scala OCaml LISP Erlang
  20. Trends of front-end MV* View Model Controller update() render()

  21. Trends of front-end MV* View Model Model Model View View

    View View View
  22. Trends of front-end MV* View Model Model Model View View

    View View View update()
  23. React's Virtual DOM VDOM Model Model Model DOM DOM DOM

    DOM VDOM VDOM VDOM
  24. React's Virtual DOM Model Model DOM DOM DOM DOM VDOM

    VDOM VDOM VDOM Model update() render()
  25. React's Virtual DOM Model Model DOM DOM VDOM VDOM VDOM

    VDOM Model update() render() DOM DOM diff exists diff exists
  26. Declarative programming comes back! render: function() { return ( <div>

    <h3>TODO</h3> <TodoList items={this.state.items} /> <form onSubmit={this.handleSubmit}> <input onChange={this.onChange} value={this.state.text} /> <button>{'Add #' + (this.state.items.length + 1)}</button> </form> </div> ); }
  27. Frameworks that uses Virtual DOM - Mercury - Mithril -

    Cape.JS - Om - Elm
  28. Immutability makes Virtual DOM faster! Old Model DOM Old VDOM

    New Model DOM New VDOM diff diff
  29. Flux, an architecture by facebook https://github.com/facebook/flux

  30. Flux, an architecture by facebook https://github.com/facebook/flux one-way data flow

  31. Flux libraries - Fluxxor - Fluxible(by Yahoo) - RefluxJS -

    McFly - Delorean
  32. FRP libraries - Rx(C#) - RxJava(Java) - RxJS(JavaScript) - Bacon.js(JavaScript)

    - Sodium(Haskell) - Reative-banana(Haskell)
  33. FRP libraries (RxJava) http://reactivex.io/RxJava/javadoc/rx/Observable.html

  34. FRP libraries (RxJava) http://reactivex.io/RxJava/javadoc/rx/Observable.html

  35. React + X Type-safety Architecture Flux Immutability Virtual DOM Reactivilty

    - Flow - Bacon.js - RxJS - Fluxible - Fluxxor + α - Immutable.js
  36. React + X Type-safety Architecture Flux Immutability Virtual DOM Reactivilty

    + α ✓ ✓ ✓ ✓
  37. About Elm - born in Apr 2012 - ver 0.15

    - designed by Evan Czaplicki (Prezi) - http://elm-lang.org/ - https://groups.google.com/forum/#! forum/elm-discuss
  38. About Elm 0.15 Apr 2015 Tasks, better HTTP library 0.14

    Dec 2014 Package manager, parallel builds, JSON --- Jul 2014 elm-html http://evancz.github.io/elm-todomvc/ Graphics.Element Html http://elm-lang.org/examples/adventure
  39. Hello, world! import Html exposing (..) main : Html main

    = text "Hello, World!" text : String → Html
  40. Hello, world! import Html exposing (..) import Html.Attributes exposing (..)

    main : Html main = ul [class "grocery-list"] [ li [] [text "Pamplemousse"] , li [] [text "Ananas"] , li [] [text "Jus d'orange"] ] ul : List Attribute → List Html → Html li : List Attribute → List Html → Html class : String → Attribute
  41. Signals import Html exposing (..) import Mouse main : Signal

    Html main = Signal.map (\p -> text (toString p)) Mouse.position Mouse.position : Signal (Int, Int) Signal.map : (a → b) → Signal a → Signal b toString : a → String
  42. Signals (10, 20) Time main : Signal Html (15, 30)

    position : Signal (Int, Int) “(10, 20)” Time “(15, 30)” map
  43. Signals import Html exposing (..) import Mouse main : Signal

    Html main = Signal.map (\count -> text (toString count)) countClick countClick : Signal Int countClick = Signal.foldp (\clk count -> count + 1) 0 Mouse.clicks Mouse.clicks : Signal () Signal.foldp : (a → b → b) → b → Signal a → Signal b
  44. Signals () Time countClick : Signal Int clicks : Signal

    (Int, Int) Time foldp () () 1 2 3
  45. You might think FRP looks like...

  46. You might think FRP looks like... keydown timestamp errors fullname

    ajax formData firstName lastName enter letter tabIndex errorCount ok messages html click submit ok error reset inputs
  47. Actually?

  48. Actually? action model html

  49. The Elm Architecture - model - update - view http://evancz.github.io/elm-todomvc/

    http://elm-lang.org/examples/adventure
  50. The Elm Architecture Model View Action Update Mailbox - model

    - update - view
  51. The Elm Architecture -- MODEL type alias Model = {

    ... } -- UPDATE type Action = Reset | ... update : Action -> Model -> Model update action model = case action of Reset -> ... ... -- VIEW view : Model -> Html view model = ...
  52. Code reading http://evancz.github.io/elm-todomvc/

  53. Model -- MODEL type alias Model = { tasks :

    List Task , field : String , uid : Int , visibility : String } type alias Task = { description : String , completed : Bool , editing : Bool , id : Int }
  54. Model newTask : String -> Int -> Task newTask desc

    id = { description = desc , completed = False , editing = False , id = id } emptyModel : Model emptyModel = { tasks = [] , visibility = "All" , field = "" , uid = 0 }
  55. Update -- UPDATE type Action = NoOp | UpdateField String

    | EditingTask Int Bool | UpdateTask Int String | Add | Delete Int | DeleteComplete | Check Int Bool | CheckAll Bool | ChangeVisibility String
  56. Update update : Action -> Model -> Model update action

    model = case action of NoOp -> model Add -> { model | uid <- model.uid + 1, field <- "", tasks <- if String.isEmpty model.field then model.tasks else model.tasks ++ [newTask model.field model.uid] } Delete id -> { model | tasks <- List.filter (\t -> t.id /= id) model.tasks } Check id isCompleted -> let updateTask t = if t.id == id then { t | completed <- isCompleted } else t in { model | tasks <- List.map updateTask model.tasks } ...
  57. View view : Address Action -> Model -> Html view

    address model = div [ class "todomvc-wrapper" , style [ ("visibility", "hidden") ] ] [ section [ id "todoapp" ] [ lazy2 taskEntry address model.field , lazy3 taskList address model.visibility model.tasks , lazy3 controls address model.visibility model.tasks ] , infoFooter ]
  58. View taskEntry : Address Action -> String -> Html taskEntry

    address task = header [ id "header" ] [ h1 [] [ text "todos" ] , input [ id "new-todo" , placeholder "What needs to be done?" , autofocus True , value task , name "newTodo" , on "input" targetValue (Signal.message address << UpdateField) , onEnter address Add ] [] ]
  59. Main main : Signal Html main = Signal.map (view actions.address)

    model model : Signal Model model = Signal.foldp update initialModel actions.signal actions : Signal.Mailbox Action actions = Signal.mailbox NoOp
  60. Good architecture makes language simple! Language Architecture ×

  61. Good architecture makes language simple! I want some function, but

    the core library doesn't support it! Q:
  62. Good architecture makes language simple! Is that really required? Maybe

    your system can be written more simply. A:
  63. No unnecessary features! Keep it simple. Please support monad! Q:

    No. A: Really need type classes! Q: No. A: Higher-kinded types... Q: No. A:
  64. Static graphs only Signal (Signal a)

  65. Static graphs only https://www.youtube.com/watch?v=Agu6jipKfYw

  66. Larger application

  67. inputView buttonView Nesting components Model View Action Mailbox

  68. inputView buttonView inputAction buttonAction Nesting components Model View Action Mailbox

    inputModel buttonModel
  69. Nesting components type ButtonAction = Click (Int, Int) | Hover

    Float | NoOp type ContainerAction = Button ButtonAction | Checkbox CheckboxAction | Inputbox InputboxAction | NoOp Button.elm Main.elm
  70. Nesting components type alias ContainerModel = { button : ButtonModel

    , input : InputModel } init : ContainerModel init = { button = Button.init , input = Input.init } Main.elm
  71. Nesting components containerAddress : Address ContainerAction buttonAddress : Address ButtonAction

    buttonAddress = Signal.forwardTo containerAddress Button checkboxAddress : Address CheckboxAction checkboxAddress = Signal.forwardTo containerAddress Checkbox inputboxAddress : Address InputboxAction inputboxAddress = Signal.forwardTo containerAddress Inputbox Main.elm
  72. Stateful components? 2 3 buttonA buttonB click +1

  73. Stateful components? updateButton : ButtonAction -> ButtonState -> ButtonState updateButton

    action state = case action of Click -> { state | count <- state.count + 1 } update : Action -> Model -> Model update action model = case action of ButtonA a -> { model | buttonA <- updateButton a model.buttonA } ButtonB b -> { model | buttonB <- updateButton b model.buttonB } Main.elm Button.elm
  74. Is Elm ready for production?

  75. Is Elm ready for production? Yes! But needs more libraries

    for productivity. type Action = Wait | Contribute
  76. Conclusion - Elm is a FRP language - Elm also

    has a good architecture - Elm is ready to use
  77. Thank you!