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

Getting to know Elm

Getting to know Elm

They say React is just a library, but it could well have changed the way you write javascript applications. What if you could take that transformation even further? Elm is a functional programming language for writing HTML apps that replaces runtime exceptions with friendly compiler error messages, and a cacophony of modules with neat tooling and conventions. If you want to write great code, you should get to know Elm. But beware; it might change the way you build HTML apps forever.

Arjan van der Gaag

November 10, 2016
Tweet

More Decks by Arjan van der Gaag

Other Decks in Programming

Transcript

  1. Arjan van der Gaag • Brightin • @avdgaag • yet

    another language • yet another framework • constantly pleasing the compiler • it’s not Haskell
  2. Arjan van der Gaag • Brightin • @avdgaag > adder

    x y = x + y
 <function> : number -> number -> number > adder 1 2
 3 : number > add1 = adder 1
 <function> : number -> number > add1 2
 3 : number
  3. Arjan van der Gaag • Brightin • @avdgaag > List.head

    [1, 2, 3]
 Just 1 : Maybe.Maybe number > List.head []
 Nothing : Maybe.Maybe a
  4. Arjan van der Gaag • Brightin • @avdgaag The left

    argument of (*) is causing a type mismatch. 3| List.head [1, 2, 3]) * 2 ^^^^^^^^^^^^^^^^^^^ (*) is expecting the left argument to be a: number But the left argument is: Maybe number
  5. Arjan van der Gaag • Brightin • @avdgaag > Maybe.map

    ((*) 2) (Just 3)
 Just 6 : Maybe.Maybe number > Maybe.map ((*) 2) Nothing
 Nothing : Maybe.Maybe number
  6. Arjan van der Gaag • Brightin • @avdgaag case List.head

    [1, 2, 3] of Just n -> workWith n Nothing -> doSomethingElse
  7. Arjan van der Gaag • Brightin • @avdgaag auto-currying functions,

    types, immutable values and
 a helpful compiler
  8. Arjan van der Gaag • Brightin • @avdgaag view =

    div [ class "wrapper" ] [ input [ type' "text" ] [] ]
  9. Arjan van der Gaag • Brightin • @avdgaag we describe

    our views using plain Elm functions
  10. Arjan van der Gaag • Brightin • @avdgaag type User

    = AnonymousUser | LoggedInUser String
  11. Arjan van der Gaag • Brightin • @avdgaag type alias

    Euros = Int type alias Cents = Int type alias Money = (Euros, Cents) type alias Model = { query : String }
  12. Arjan van der Gaag • Brightin • @avdgaag view =

    div [ class "wrapper" ] [ input [ type' “text" ] [] ]
  13. Arjan van der Gaag • Brightin • @avdgaag view model

    = div [ class "wrapper" ] [ input [ type' “text" ] [] ]
  14. Arjan van der Gaag • Brightin • @avdgaag view model

    = div [ class "wrapper" ] [ input [ type' "text" , value model.query ] [] ]
  15. Arjan van der Gaag • Brightin • @avdgaag we model

    our domain with types, helping us make impossible states impossible
  16. Arjan van der Gaag • Brightin • @avdgaag view :

    Model -> Html Msg view model = div [ class "wrapper" ] [ input [ type' "text" , value model.query ] [] ]
  17. Arjan van der Gaag • Brightin • @avdgaag view :

    Model -> Html Msg view model = div [ class "wrapper" ] [ input [ type' "text" , value model.query , onInput SetQueryText ] [] ]
  18. Arjan van der Gaag • Brightin • @avdgaag update :

    Msg -> Model -> Model
 update msg model = case msg of
 NoOp -> model
  19. Arjan van der Gaag • Brightin • @avdgaag This `case`

    does not have branches for all possibilities. 60|> case msg of 61|> NoOp -> 62|> model ! [] 63|> You need to account for the following values: Main.SetQueryText _ Add a branch to cover this pattern! If you are seeing this error for the first time, check out these hints: <https://github.com/elm-lang/elm-compiler/blob/0.17.1/hints/missing-patterns.md> The recommendations about wildcard patterns and `Debug.crash` are important! Detected errors in 1 module.
  20. Arjan van der Gaag • Brightin • @avdgaag update :

    Msg -> Model -> Model update msg model = case msg of NoOp -> model SetQueryText str -> { model | query = str }
  21. Arjan van der Gaag • Brightin • @avdgaag we explicitly

    describe all mutations in our system
  22. Arjan van der Gaag • Brightin • @avdgaag update :

    Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of SetQueryText str -> ( { model | query = str } , getSuggestions str )
  23. Arjan van der Gaag • Brightin • @avdgaag update :

    Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of SetQueryText str -> ( { model | query = str } , getSuggestions str )
  24. Arjan van der Gaag • Brightin • @avdgaag getSuggestions :

    String -> Cmd Msg getSuggestions query = let url = Http.url "http://example.com" [("term", query)] task = Http.get callback url in Task.perform Failure Success task
  25. Arjan van der Gaag • Brightin • @avdgaag getSuggestions :

    String -> Cmd Msg getSuggestions query = let url = Http.url "http://example.com" [("term", query)] task = Http.get callback url in Task.perform Failure Success task
  26. Arjan van der Gaag • Brightin • @avdgaag getSuggestions :

    String -> Cmd Msg getSuggestions query = let url = Http.url "http://example.com" [("term", query)] task = Http.get callback url in Task.perform Failure Success task
  27. Arjan van der Gaag • Brightin • @avdgaag getSuggestions :

    String -> Cmd Msg getSuggestions query = let url = Http.url "http://example.com" [("term", query)] task = Http.get callback url in Task.perform Failure Success task
  28. Arjan van der Gaag • Brightin • @avdgaag type Msg

    = NoOp | SetQueryText String | Failure Http.Error | Success (List String)
  29. Arjan van der Gaag • Brightin • @avdgaag the elm

    runtime explicitly handles side effects
  30. Arjan van der Gaag • Brightin • @avdgaag getSuggestions :

    String -> Cmd Msg getSuggestions query = let url = Http.url "http://example.com" [("term", query)] task = Http.get callback url in Task.perform Failure Success task
  31. Arjan van der Gaag • Brightin • @avdgaag getSuggestions :

    String -> Cmd Msg getSuggestions query = let url = Http.url "http://example.com" [("term", query)] task = Http.get callback url in Task.perform Failure Success task
  32. Arjan van der Gaag • Brightin • @avdgaag getSuggestions :

    String -> Cmd Msg getSuggestions query = let url = Http.url "http://example.com" [("term", query)] task = Http.get decodeSuggestions url in Task.perform Failure Success task
  33. Arjan van der Gaag • Brightin • @avdgaag -- ["term1",

    "term2"] decodeSuggestions : Json.Decode.Decoder Model decodeSuggestions = Json.Decode.list Json.Decode.string
  34. Arjan van der Gaag • Brightin • @avdgaag type alias

    Person = { name : String , age : Int , profession : Maybe String } person : Decoder Person person = object3 Person ("name" := string) ("age" := int) (maybe ("profession" := string))
  35. Arjan van der Gaag • Brightin • @avdgaag • helpful

    compiler • explicit domain modeling • explicit side effects via the Elm runtime • predictable architecture