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

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. A delightful language for reliable webapps.
 Generate JavaScript with great

    performance and no runtime exceptions. http://elm-lang.org
  2. • 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?
  3. Elm has two major features: 
 (1) purely functional graphical

    layout and 
 (2) support for Concurrent FRP.
  4. 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.
  5. 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…
  6. 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.
  7. 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!
  8. 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
  9. 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.
  10. main : Program Never Model Msg main = Html.program {

    init = init , view = view , update = update , subscriptions = subscriptions }
  11. type alias Model = {} init : ( Model, Cmd

    Msg ) init = ( {}, Cmd.none )
  12. type Msg = NoOp update : Msg -> Model ->

    ( Model, Cmd Msg ) update msg model = ( model, Cmd.none )
  13. 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
  14. type alias Model = { greeting : String } init

    : ( Model, Cmd Msg ) init = ( { greetng = “Hello, Code Driven!” } , Cmd.none )
  15. -- 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.
  16. type alias Model = { greeting : String , diceRoll

    : Int } init : ( Model, Cmd Msg ) init = ( { greeting = "Hello, Code Driven!” , diceRoll = 0 } , Cmd.none )
  17. 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" ] ]
  18. 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 )
  19. import Elm from 'react-elm-components' import { Todo } from '../dist/elm/todomvc.js'

    function render() { return <Elm src={Todo} /> } http://elm-lang.org/blog/how-to-use-elm-at-work
  20. “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.”
  21. ^D