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

Short Intro to Elm concepts

Taku Okawa
January 07, 2017

Short Intro to Elm concepts

Slides of my talk at Enigmo's(http://www.enigmo.co.jp/) weekly tech talk series(Hacker's delight).

Taku Okawa

January 07, 2017
Tweet

More Decks by Taku Okawa

Other Decks in Programming

Transcript

  1. WHAT IS ELM? Elm is a domain-speci c programming language

    for declaratively creating web browser-based graphical user interfaces. Elm is purely functional, and is developed with emphasis on usability, performance, and robustness. Tools elm repl : repl elm reactor : development server elm make : compiler elm package : package manager
  2. IN PRACTICE Null safe(No runtime error. 'unde ned is not

    a function' can't happen) Compiler Errors for Humans Mostly one way to do it(Hard to write bad code) All in one (redux/ramda.js/ ow.js/data.maybe/immutable.js ...)
  3. ELM ARCHITECTURE Model - the state of your application Update

    - a way to update your state View - a way to view your state as HTML
  4. http://elm-lang.org/examples/buttons import Html exposing (Html, button, div, text) import Html.Events

    exposing (onClick) main = Html.beginnerProgram { model = model, view = view, update = update } -- MODEL type alias Model = Int model : Model model = 0 -- UPDATE type Msg = Increment | Decrement update : Msg -> Model -> Model update msg model = case msg of Increment -> model + 1
  5. TYPES type Message = Increment | Decrement type Message is

    either Icrement or Decrement. type User = Anonymous | Named String Type User is either Anonymous, or String Named is also a constructor, and used for creating the value(Named "John") type Tree a = Empty | Node a (Tree a) (Tree a) represents a binary tree type Tree is Either Empty, or a node of kind 'a' (convention for any type)
  6. RECORD { title = "Steppenwolf", author = "Hesse", pages =

    237 } Labeled light weight structure type alias Point = { x : Float , y : Float } Type alias to de ne record structure { point2D | y = 1 } -- { x=0, y=1 } { point3D | x = 0, y = 0 } -- { x=0, y=0, z=12 } { steve | name = "Wozniak" } -- { name="Wozniak", age=56 } Update elds
  7. PATTERN MATCHING type Message = Increment | Decrement | Restore

    Int | NoOp case msg of Increment -> "increment" Decrement -> "decrement" Restore count -> toString count _ -> "" _ to capture the other patterns Compiler detects non-exhausive conditions type alias Coupon = { id: String, expireDate: Maybe String } let coupon = { id = "abc", expireDate = Just "2016-12-12" } in case coupon.expireDate of Just date -> date Nothing -> "" -- (oneliner) Maybe.withDefault "" coupon.expireDate
  8. PATTERN MATCHING maximum : List comparable -> Maybe comparable maximum

    list = case list of x :: xs -> Just (foldl max x xs) _ -> Nothing Destructure list element and assign variables(x for rst elment, xs for the rest elements) Elm Destructuring (or Pattern Matching) cheatsheet
  9. EFFECTS Commands A Cmd lets you do stu Subscriptions A

    Sub lets you register that you are interested in something
  10. COMMAND type Msg = Click | NewBook (Result Http.Error String)

    type alias Model = String update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of Click -> ( model, getWarAndPeace ) NewBook (Ok book) -> ( book, Cmd.none) NewBook (Err _) -> ( model, Cmd.none) getWarAndPeace : Cmd Msg getWarAndPeace = let request = Http.getString NewBook "/" in Http.send request Pass commands to elm runtime When a command nishses, update is called with Result type
  11. SPLIT NESTED CONDITIONS INTO MODULES type Msg = .... |

    OrderList | OrderDetail String | OrderSearch String update: Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of ... OrderList -> ... OrdersDetail orderId -> ... OrderSearch productName -> ... branches gets longer and longer
  12. SPLIT NESTED CONDITIONS INTO MODULES(COND) type Msg = ... |

    OrderMessage Order.Msg update: Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of ... OrdersMessage subMessage -> let (orderModel, orderMessage) = Orders.Update.update subMessage model. in ({model|order=orderModel}, Cmd.map OrdersMessage orderMessage) Split branches into sub modules
  13. USE INFIX OPERATORS TO IMPROVE READABILITY ngon 5 30 |>

    filled blue |> move (10,10) |> scale 2 forward function application == cleaner than below scale 2 (move (10,10) (filled blue (ngon 5 30))) args comes rst(left side), and |> is left- associative(meaning a |> b |> c |> d is ((a |> b) |> c) |> d ) That's why we don't need to specify precedence with parentheses
  14. USE INFIX OPERATORS TO IMPROVE READABILITY(COND) leftAligned <| monospace <|

    fromString "code" backwoard function application == leftAligned (monospace (fromString "code")) is right-associative(meaning is a )