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

Introduction to Elm

Introduction to Elm

Introduction to the Elm language, principles, ecosystem and architecture

Rogério Chaves

February 17, 2016
Tweet

More Decks by Rogério Chaves

Other Decks in Technology

Transcript

  1. WHAT IS ELM? 2 •4 years old language •Compile to

    JS •Front-end focus •Simplicity focus •FRP focus
  2. CHARACTERISTICS 3 •Functional •ML syntax •Immutability •Pure functions •Strong type

    system, but: •No typeclasses •No higher kinded types •Functional reactive programming
  3. 4 DO I REALLY NEED TO LEARN
 A NEW LANGUAGE?


    
 LET’S JUST USE JAVASCRIPT!
  4. 5 Elm JS ES6 + Babel + Webpack + React

    + Redux + Immutable or Typescript or Brunch or Gulp or Grunt or Cycle.js + RxJS or seamless-
 immutable Not even close
  5. 7

  6. 8

  7. 9

  8. 12 A LITTLE MORE OBVIOUS SYNTAX -- isNotEven = not

    . isEven isNotEven = not << isEven isNotEven' = isEven >> not -- let lastChar = head $ toList $ reverse "foobar" let lastChar = head <| toList <| reverse "foobar" dot = scale 2 (move (20,20) (filled blue (circle 10))) dot' = circle 10 |> filled blue |> move (20,20) |> scale 2
  9. 13 RECORDS carolina = { name = "Carolina de Jesus"

    , age = 62 } abdias = { name = "Abdias Nascimento" , age = 97 } people = [ carolina , abdias ] carolina.name .name carolina List.map .name people -- ["Carolina de Jesus", "Abdias Nascimento"]
  10. 15

  11. 16

  12. 26 SIGNALS import Graphics.Element exposing (..) import Mouse main :

    Signal Element main = Signal.map show Mouse.position
  13. 29 module Counter where import Html exposing (..) import Html.Attributes

    exposing (style) import Html.Events exposing (onClick) -- MODEL type alias Model = Int -- UPDATE type Action = Increment | Decrement update : Action -> Model -> Model update action model = COUNTER.ELM
  14. -- UPDATE type Action = Increment | Decrement update :

    Action -> Model -> Model update action model = case action of Increment -> model + 1 Decrement -> model - 1 -- VIEW view : Signal.Address Action -> Model -> Html view address model = div [] [ button [ onClick address Decrement ] [ text "-" ] , div [ countStyle ] [ text (toString model) ] 30 COUNTER.ELM
  15. -- VIEW view : Signal.Address Action -> Model -> Html

    view address model = div [] [ button [ onClick address Decrement ] [ text "-" ] , div [ countStyle ] [ text (toString model) ] , button [ onClick address Increment ] [ text "+" ] ] countStyle : Attribute countStyle = style [ ("font-size", "20px") , ("font-family", "monospace") , ("display", "inline-block") , ("width", "50px") , ("text-align", "center") ] 31 COUNTER.ELM
  16. 32 MAIN.ELM import Counter exposing (update, view) import StartApp.Simple exposing

    (start) main = start { model = 0 , update = update , view = view } http://evancz.github.io/elm-architecture-tutorial/examples/1
  17. 34 EFFECTS type Action = RequestMore | NewGif (Maybe String)

    update : Action -> Model -> (Model, Effects Action) update action model = case action of RequestMore -> (model, getRandomGif model.topic) NewGif maybeUrl -> ( Model model.topic (Maybe.withDefault model.gifUrl maybeUrl) , Effects.none )
  18. 35 TASKS getRandomGif : String -> Effects Action getRandomGif topic

    = Http.get decodeUrl (randomUrl topic) |> Task.toMaybe |> Task.map NewGif |> Effects.task randomUrl : String -> String randomUrl topic = Http.url "http://api.giphy.com/v1/gifs/random" [ "api_key" => "dc6zaTOxFJmzC" , "tag" => topic ]
  19. 39 ELM TEST module Example where import ElmTest exposing (..)

    tests : Test tests = suite "A Test Suite" [ test "Addition" <| assertEqual (3 + 7) 10 , test "This test should fail" <| assert False ]
  20. 40 ELM TEST BDD STYLE module Example where import ElmTestBDDStyle

    exposing (..) tests : Test tests = describe "A Test Suite" [ it "adds two numbers" <| expect (3 + 7) toBe 10 , it "fails for non-sense stuff" <| expect True toBe False ]
  21. 41 PROPERTY-BASED TESTING module Example where import ElmTestBDDStyle exposing (..)

    import Check.Investigator exposing (..) tests : Test tests = describe "A Test Suite" [ it "adds two numbers" <| expect (3 + 7) toBe 10 , it "fails for non-sense stuff" <| expect True toBe False , itAlways "ends up with the same list when reversing twice" <| expectThat (\list -> List.reverse (List.reverse list)) isTheSameAs (identity) forEvery (list int) ]
  22. 43 FROM JS TO ELM port addUser : Signal (String,

    UserRecord) myapp.ports.addUser.send([ "Tom", { age: 32, job: "lumberjack" } ]); myapp.ports.addUser.send([ "Sue", { age: 37, job: "accountant" } ]); JS
  23. 44 FROM ELM TO JS port requestUser : Signal String

    port requestUser = signalOfUsersWeWantMoreInfoOn myapp.ports.requestUser.subscribe(databaseLookup); function databaseLookup(user) { var userInfo = database.lookup(user); myapp.ports.addUser.send(user, userInfo); } JS