$30 off During Our Annual Pro Sale. View Details »

Elm: In Theory & In Practice

Elm: In Theory & In Practice

Given at FirstMark Capital's Code Driven NYC in March 2017.

Mark Wunsch

March 22, 2017
Tweet

More Decks by Mark Wunsch

Other Decks in Programming

Transcript

  1. Elm
    Theory & Practice
    @markwunsch

    View Slide

  2. tinyletter.com/wunsch

    View Slide

  3. A delightful language for
    reliable webapps.

    Generate JavaScript with great
    performance and no runtime exceptions.
    http://elm-lang.org

    View Slide

  4. Study of an Elm Tree
    John Constable, 1821

    View Slide

  5. • Where does Elm come from?
    • What makes it reliable?
    • How am I using it?
    • How can you use it?
    • Why would you want to do such a thing?

    View Slide

  6. Theory

    View Slide

  7. View Slide

  8. Where does Elm come from?

    View Slide

  9. View Slide

  10. Elm has two major features: 

    (1) purely functional graphical layout and 

    (2) support for Concurrent FRP.

    View Slide

  11. Concurrent FRP solves some of FRP’s long-
    standing efficiency problems: 

    global delays and needless recomputation.

    View Slide

  12. Needless recomputation occurs when a
    function is recomputed even though its
    input has not changed.

    View Slide

  13. Initial Public Release

    v0.3.0
    May 29, 2013

    View Slide

  14. Functional Reactive
    Programming

    View Slide

  15. View Slide

  16. Functional Reactive Programming (FRP) is a
    declarative programming paradigm for
    working with mutable values. FRP recasts
    mutable values as time-varying values,
    better capturing the temporal aspect of
    mutability.

    View Slide

  17. Signal α = Time → α

    View Slide

  18. What makes it reliable?

    View Slide

  19. The core language of Elm aims to provide
    flexibility and expressiveness, yet only commit
    to abstractions that can be implemented
    efficiently in a concurrent system…

    View Slide

  20. In Elm, no event occurs at exactly the same moment
    as another. This ensures that there is a strict ordering
    of events, and simplifies the mental model for
    events: events happen one at a time. The exact co-
    occurrence of events is also extremely uncommon in
    GUIs which deal primarily with user input. On the
    time-scale of computers, users are slow enough that
    user input events really are strictly ordered.

    View Slide

  21. http://redux.js.org

    View Slide

  22. View Slide

  23. So is Elm about FRP anymore? No. Those days are
    over now. Elm is just a functional language that takes
    concurrency very seriously. And from a user's
    perspective, 
Elm is just a friendly functional
    language!

    View Slide

  24. Elm is just a friendly functional
    language!

    View Slide

  25. Practice

    View Slide

  26. The Elm Architecture

    View Slide

  27. module Main exposing (..)
    import Html exposing (..)
    main : Program Never Model Msg
    main =
    Html.program
    { init = init
    , view = view
    , update = update
    , subscriptions = subscriptions
    }
    type alias Model =
    {}
    init : ( Model, Cmd Msg )
    init =
    ( {}, Cmd.none )
    type Msg
    = NoOp
    update : Msg -> Model -> ( Model, Cmd Msg )
    update msg model =
    ( model, Cmd.none )
    subscriptions : Model -> Sub Msg
    subscriptions model =
    Sub.none
    view : Model -> Html Msg
    view model =
    Html.text "Hello, world!"
    B
    O
    ILER
    P
    LA
    TE

    View Slide

  28. https://gist.github.com/mwunsch/
    99e70f774a9f065bac778aed505d4f9b

    View Slide

  29. module Main exposing (..)
    -- Declare a Main module and expose

    -- everything to the public.

    -- This is a comment, btw.
    import Html exposing (..)
    -- Import everything in the Html module.

    View Slide

  30. main : Program Never Model Msg
    main =
    Html.program
    { init = init
    , view = view
    , update = update
    , subscriptions = subscriptions
    }

    View Slide

  31. type alias Model =
    {}
    init : ( Model, Cmd Msg )
    init =
    ( {}, Cmd.none )

    View Slide

  32. type Msg
    = NoOp
    update : Msg -> Model -> ( Model, Cmd Msg )
    update msg model =
    ( model, Cmd.none )

    View Slide

  33. subscriptions : Model -> Sub Msg
    subscriptions model =
    Sub.none

    View Slide

  34. view : Model -> Html Msg
    view model =
    Html.text "Hello, world!"

    View Slide

  35. type alias Model =
    { greeting : String }
    init : ( Model, Cmd Msg )
    init =
    ( { greeting = “Hello, Code Driven!” }
    , Cmd.none
    )

    view : Model -> Html Msg
    view model =
    Html.text model.greeting

    View Slide

  36. View Slide

  37. type alias Model =
    { greeting : String }
    init : ( Model, Cmd Msg )
    init =
    ( { greetng = “Hello, Code Driven!” }
    , Cmd.none
    )

    View Slide

  38. -- TYPE MISMATCH ------------------------------------------------------ Main.elm
    The definition of `init` does not match its type annotation.
    27| init : ( Model, Cmd Msg )
    28| init =
    29|> ( { greetng = "Hello, Code Driven!" }
    30|> , Cmd.none
    31|> )
    The type annotation for `init` says it is a:
    ( Model, Cmd Msg )
    But the definition (shown above) is a:
    ( { greetng : String }, Cmd msg )
    Hint: The record fields do not match up. Maybe you made one of these typos?
    greeting <-> greetng
    Detected errors in 1 module.

    View Slide

  39. How am I using it?

    View Slide

  40. Random.generate : ( a → msg ) → Random.Generator a → Cmd msg

    View Slide

  41. import Html.Attributes exposing (style)
    import Html.Events exposing (onClick)
    import Random

    View Slide

  42. type alias Model =
    { greeting : String
    , diceRoll : Int
    }
    init : ( Model, Cmd Msg )
    init =
    ( { greeting = "Hello, Code Driven!”
    , diceRoll = 0
    }
    , Cmd.none
    )

    View Slide

  43. type Msg
    = ButtonClick
    | Roll Int

    View Slide

  44. view : Model -> Html Msg
    view model =
    div [ style [ ( "margin", "20px" ) ] ]
    [ h1 [] [ text model.greeting ]
    , h2 [] [ text ("You rolled a " ++ (toString model.diceRoll)) ]
    , button
    [ style [ ( "font-size", "2em" ) ]
    , onClick ButtonClick
    ]
    [ text "\x1f3b2" ]
    ]

    View Slide

  45. type Msg
    = ButtonClick
    | Roll Int
    update : Msg -> Model -> ( Model, Cmd Msg )
    update msg model =
    case msg of
    ButtonClick ->
    ( model, Random.generate Roll (Random.int 1 20) )
    Roll result ->
    ( { model
    | diceRoll = result
    , greeting =
    if result >= 20 then
    "Hello, Crit Driven!"
    else
    "Hello, Code Driven!"
    }
    , Cmd.none
    )

    View Slide

  46. View Slide

  47. View Slide

  48. View Slide

  49. github.com/mwunsch/hive-city/

    View Slide

  50. How can you use it?

    View Slide

  51. import Elm from 'react-elm-components'
    import { Todo } from '../dist/elm/todomvc.js'
    function render() {
    return
    }
    http://elm-lang.org/blog/how-to-use-elm-at-work

    View Slide

  52. Why would you want to do
    such a thing?

    View Slide

  53. Let’s be mainstream!
    User focused design in Elm

    http://www.elmbark.com/2016/03/16/mainstream-elm-user-focused-design

    View Slide

  54. “Easy to reason about. It’s not really clear what
    that’s going to give me. Was it hard to reason
    about? I’m a JavaScript programmer, I spend a
    lot of time reasoning about what my code
    does because weird stuff can happen.”

    View Slide

  55. State & Time
    https://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

    View Slide

  56. @markwunsch
    tinyletter.com/wunsch

    View Slide

  57. The School of Athens
    Raphael, 1509–1511

    View Slide

  58. ^D

    View Slide