Introduction to Elm

Post on 07-Jan-2017

530 views 1 download

Transcript of Introduction to Elm

INTRODUCTION TO ELM

WHAT IS ELM?

2

•4 years old language

•Compile to JS

•Front-end focus

•Simplicity focus

•FRP focus

CHARACTERISTICS

3

•Functional

•ML syntax

•Immutability

•Pure functions

•Strong type system, but:

•No typeclasses

•No higher kinded types

•Functional reactive programming

4

DO I REALLY NEED TO LEARNA NEW LANGUAGE?

LET’S JUST USE JAVASCRIPT!

5

Elm

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

Typescriptor

Brunchor

Gulpor

Grunt

or

Cycle.js + RxJSor

seamless- immutableNot even close

6

ELM MAKEThe compiler that talks to you

7

8

9

NO RUNTIME EXCEPTIONS

10

NO RUNTIME EXCEPTIONS

11

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

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"]

14

ELM REPLJust a regular REPL

15

16

17

ELM PACKAGEThe best package manager ever

18

ENFORCED SEMVER

19

ENFORCED SEMVER

20

AUTOMATIC CHANGELOG

21

ENFORCED DOCS

22

ELM REACTORAwesome development flow

ELM REACTOR

23

•Auto compile Elm

•Hot-swapping

•Time travel debugging

24

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

25

THE ELM ARCHITECTURE

26

SIGNALS

import Graphics.Element exposing (..)import Mouse

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

27

Update

Model

Viewaction

signal mailbox

28

talk is cheap, show me the code

29

moduleCounterwhere

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

--MODEL

typealiasModel=Int

--UPDATE

typeAction=Increment|Decrement

update:Action->Model->Modelupdateactionmodel=caseactionof

COUNTER.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

--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

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

33

side-effects

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 )

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 ]

36

invention or discovery?

37

try to escape the Elm Architecture, I dare you!

38

TESTSOnly for checking what the compiler can’t

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 ]

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 ]

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) ]

42

JS

JAVASCRIPT INTEROP

Avoid it at all costs

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

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

45

NATIVE JS INTEROP

DON’T USE THIS

THANK YOU