Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Yosuke Torii

July 01, 2015
Tweet

More Decks by Yosuke Torii

Other Decks in Programming

Transcript

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

    View Slide

  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

    View Slide

  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!"]

    View Slide

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

    View Slide

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

    View Slide

  6. Reactive Programming
    a b
    c
    +
    1 1
    2

    View Slide

  7. Reactive Programming
    a b
    c
    +
    1 2
    3

    View Slide

  8. Reactive Programming
    a b
    c
    +
    2 2
    4

    View Slide

  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!

    View Slide

  10. Functional Reactive Programming
    2
    1 Time
    a
    Signal
    : function of time

    View Slide

  11. Functional Reactive Programming
    2
    1
    2
    1
    Time
    Time
    a
    b

    View Slide

  12. Functional Reactive Programming
    2
    1
    2
    1
    Time
    Time
    4
    2 Time
    3
    1
    a
    b
    c

    View Slide

  13. Basis of FRP
    2
    1
    4
    2
    Time
    Time
    a
    b
    map

    View Slide

  14. Basis of FRP
    3
    1 Time
    Time
    a
    b
    filter
    4
    2
    4
    2

    View Slide

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

    View Slide

  16. Basis of FRP
    1
    1 Time
    Time
    a
    b
    merge
    2
    2
    Time
    c 1
    1 2
    2

    View Slide

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

    View Slide

  18. FRP meets MV* architecture
    Action
    Model
    View Hello, John Smith!
    John Smith
    John Smith
    keydown keydown

    View Slide

  19. FRP meets MV* architecture
    MV* FP
    Elm
    AngularJS
    Backbone.js
    React.js
    Ember.js
    Haskell
    Scala
    OCaml
    LISP
    Erlang

    View Slide

  20. Trends of front-end MV*
    View
    Model
    Controller
    update()
    render()

    View Slide

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

    View Slide

  22. Trends of front-end MV*
    View
    Model Model
    Model
    View View
    View
    View
    View
    update()

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  26. Declarative programming comes back!
    render: function() {
    return (

    TODO



    {'Add #' + (this.state.items.length + 1)}


    );
    }

    View Slide

  27. Frameworks that uses Virtual DOM
    - Mercury
    - Mithril
    - Cape.JS
    - Om
    - Elm

    View Slide

  28. Immutability makes Virtual DOM faster!
    Old
    Model
    DOM
    Old
    VDOM
    New
    Model
    DOM
    New
    VDOM
    diff
    diff

    View Slide

  29. Flux, an architecture by facebook
    https://github.com/facebook/flux

    View Slide

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

    View Slide

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

    View Slide

  32. FRP libraries
    - Rx(C#)
    - RxJava(Java)
    - RxJS(JavaScript)
    - Bacon.js(JavaScript)
    - Sodium(Haskell)
    - Reative-banana(Haskell)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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




    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  42. Signals
    (10, 20) Time
    main : Signal Html
    (15, 30)
    position : Signal (Int, Int)
    “(10, 20)” Time
    “(15, 30)”
    map

    View Slide

  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

    View Slide

  44. Signals
    () Time
    countClick : Signal Int
    clicks : Signal (Int, Int)
    Time
    foldp
    () ()
    1 2 3

    View Slide

  45. You might think FRP looks like...

    View Slide

  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

    View Slide

  47. Actually?

    View Slide

  48. Actually?
    action
    model
    html

    View Slide

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

    View Slide

  50. The Elm Architecture
    Model
    View
    Action
    Update
    Mailbox
    - model
    - update
    - view

    View Slide

  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 =
    ...

    View Slide

  52. Code reading
    http://evancz.github.io/elm-todomvc/

    View Slide

  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
    }

    View Slide

  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
    }

    View Slide

  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

    View Slide

  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 }
    ...

    View Slide

  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
    ]

    View Slide

  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
    ]
    []
    ]

    View Slide

  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

    View Slide

  60. Good architecture makes language simple!
    Language
    Architecture
    ×

    View Slide

  61. Good architecture makes language simple!
    I want some function, but
    the core library doesn't
    support it!
    Q:

    View Slide

  62. Good architecture makes language simple!
    Is that really required?
    Maybe your system can be
    written more simply.
    A:

    View Slide

  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:

    View Slide

  64. Static graphs only
    Signal (Signal a)

    View Slide

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

    View Slide

  66. Larger application

    View Slide

  67. inputView
    buttonView
    Nesting components
    Model
    View
    Action
    Mailbox

    View Slide

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

    View Slide

  69. Nesting components
    type ButtonAction
    = Click (Int, Int)
    | Hover Float
    | NoOp
    type ContainerAction
    = Button ButtonAction
    | Checkbox CheckboxAction
    | Inputbox InputboxAction
    | NoOp
    Button.elm
    Main.elm

    View Slide

  70. Nesting components
    type alias ContainerModel =
    { button : ButtonModel
    , input : InputModel
    }
    init : ContainerModel
    init =
    { button = Button.init
    , input = Input.init
    }
    Main.elm

    View Slide

  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

    View Slide

  72. Stateful components?
    2
    3
    buttonA
    buttonB
    click
    +1

    View Slide

  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

    View Slide

  74. Is Elm ready for production?

    View Slide

  75. Is Elm ready for production?
    Yes!
    But needs more libraries for productivity.
    type Action = Wait | Contribute

    View Slide

  76. Conclusion
    - Elm is a FRP language
    - Elm also has a good architecture
    - Elm is ready to use

    View Slide

  77. Thank you!

    View Slide