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

Short Intro to Elm concepts

Avatar for Taku Okawa 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).

Avatar for Taku Okawa

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 )