introduction to elm

46
INTRODUCTION TO ELM

Upload: rogerio-chaves

Post on 07-Jan-2017

530 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Introduction to Elm

INTRODUCTION TO ELM

Page 2: Introduction to Elm

WHAT IS ELM?

2

•4 years old language

•Compile to JS

•Front-end focus

•Simplicity focus

•FRP focus

Page 3: Introduction to Elm

CHARACTERISTICS

3

•Functional

•ML syntax

•Immutability

•Pure functions

•Strong type system, but:

•No typeclasses

•No higher kinded types

•Functional reactive programming

Page 4: Introduction to Elm

4

DO I REALLY NEED TO LEARNA NEW LANGUAGE?

LET’S JUST USE JAVASCRIPT!

Page 5: Introduction to Elm

5

Elm

JS ES6 + Babel + Webpack + React + Redux + Immutableor

Typescriptor

Brunchor

Gulpor

Grunt

or

Cycle.js + RxJSor

seamless- immutableNot even close

Page 6: Introduction to Elm

6

ELM MAKEThe compiler that talks to you

Page 7: Introduction to Elm

7

Page 8: Introduction to Elm

8

Page 9: Introduction to Elm

9

Page 10: Introduction to Elm

NO RUNTIME EXCEPTIONS

10

Page 11: Introduction to Elm

NO RUNTIME EXCEPTIONS

11

Page 12: Introduction to Elm

12

A LITTLE MORE OBVIOUS SYNTAX

-- isNotEven = not . isEvenisNotEven = 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

Page 13: Introduction to Elm

13

RECORDScarolina = { 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"]

Page 14: Introduction to Elm

14

ELM REPLJust a regular REPL

Page 15: Introduction to Elm

15

Page 16: Introduction to Elm

16

Page 17: Introduction to Elm

17

ELM PACKAGEThe best package manager ever

Page 18: Introduction to Elm

18

ENFORCED SEMVER

Page 19: Introduction to Elm

19

ENFORCED SEMVER

Page 20: Introduction to Elm

20

AUTOMATIC CHANGELOG

Page 21: Introduction to Elm

21

ENFORCED DOCS

Page 22: Introduction to Elm

22

ELM REACTORAwesome development flow

Page 23: Introduction to Elm

ELM REACTOR

23

•Auto compile Elm

•Hot-swapping

•Time travel debugging

Page 24: Introduction to Elm

24

EXAMPLEhttp://debug.elm-lang.org/edit/Mario.elm

Page 25: Introduction to Elm

25

THE ELM ARCHITECTURE

Page 26: Introduction to Elm

26

SIGNALS

import Graphics.Element exposing (..)import Mouse

main : Signal Elementmain = Signal.map show Mouse.position

Page 27: Introduction to Elm

27

Update

Model

Viewaction

signal mailbox

Page 28: Introduction to Elm

28

talk is cheap, show me the code

Page 29: Introduction to Elm

29

moduleCounterwhere

importHtmlexposing(..)importHtml.Attributesexposing(style)importHtml.Eventsexposing(onClick)

--MODEL

typealiasModel=Int

--UPDATE

typeAction=Increment|Decrement

update:Action->Model->Modelupdateactionmodel=caseactionof

COUNTER.ELM

Page 30: Introduction to Elm

--UPDATE

typeAction=Increment|Decrement

update:Action->Model->Modelupdateactionmodel=caseactionofIncrement->model+1

Decrement->model-1

--VIEW

view:Signal.AddressAction->Model->Htmlviewaddressmodel=div[][button[onClickaddressDecrement][text"-"],div[countStyle][text(toStringmodel)],button[onClickaddressIncrement][text"+"]

30

COUNTER.ELM

Page 31: Introduction to Elm

--VIEW

view:Signal.AddressAction->Model->Htmlviewaddressmodel=div[][button[onClickaddressDecrement][text"-"],div[countStyle][text(toStringmodel)],button[onClickaddressIncrement][text"+"]]

countStyle:AttributecountStyle=style[("font-size","20px"),("font-family","monospace"),("display","inline-block"),("width","50px"),("text-align","center")]

31

COUNTER.ELM

Page 32: Introduction to Elm

32

MAIN.ELM

importCounterexposing(update,view)importStartApp.Simpleexposing(start)

main=start{model=0,update=update,view=view}

http://evancz.github.io/elm-architecture-tutorial/examples/1

Page 33: Introduction to Elm

33

side-effects

Page 34: Introduction to Elm

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 )

Page 35: Introduction to Elm

35

TASKS

getRandomGif : String -> Effects ActiongetRandomGif topic = Http.get decodeUrl (randomUrl topic) |> Task.toMaybe |> Task.map NewGif |> Effects.task

randomUrl : String -> StringrandomUrl topic = Http.url "http://api.giphy.com/v1/gifs/random" [ "api_key" => "dc6zaTOxFJmzC" , "tag" => topic ]

Page 36: Introduction to Elm

36

invention or discovery?

Page 37: Introduction to Elm

37

try to escape the Elm Architecture, I dare you!

Page 38: Introduction to Elm

38

TESTSOnly for checking what the compiler can’t

Page 39: Introduction to Elm

39

ELM TEST

module Example where

import ElmTest exposing (..)

tests : Testtests = suite "A Test Suite" [ test "Addition" <| assertEqual (3 + 7) 10

, test "This test should fail" <| assert False ]

Page 40: Introduction to Elm

40

ELM TEST BDD STYLE

module Example where

import ElmTestBDDStyle exposing (..)

tests : Testtests = describe "A Test Suite" [ it "adds two numbers" <| expect (3 + 7) toBe 10

, it "fails for non-sense stuff" <| expect True toBe False ]

Page 41: Introduction to Elm

41

PROPERTY-BASED TESTINGmodule Example where

import ElmTestBDDStyle exposing (..)import Check.Investigator exposing (..)

tests : Testtests = 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) ]

Page 42: Introduction to Elm

42

JS

JAVASCRIPT INTEROP

Avoid it at all costs

Page 43: Introduction to Elm

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

Page 44: Introduction to Elm

44

FROM ELM TO JS

port requestUser : Signal Stringport requestUser = signalOfUsersWeWantMoreInfoOn

myapp.ports.requestUser.subscribe(databaseLookup);

function databaseLookup(user) { var userInfo = database.lookup(user); myapp.ports.addUser.send(user, userInfo);}

JS

Page 45: Introduction to Elm

45

NATIVE JS INTEROP

DON’T USE THIS

Page 46: Introduction to Elm

THANK YOU