my adventure with elm (lambdacon15)

199
BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm

Upload: yan-cui

Post on 16-Jul-2015

1.180 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 LambdaCon

Yan Cui (@theburningmonk)my adventure with Elm

Page 2: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

agenda

Page 3: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Hi, my name is Yan Cui.

Page 4: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 5: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

I’m not an expert on Elm.

Page 6: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 7: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Function Reactive Programming?

Page 8: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Value over Time

Page 9: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Time

Value

Page 10: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Time

ValueSignal

Page 11: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 12: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

?

Page 13: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 14: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 15: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

SignalVariable

Page 16: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 17: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 18: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Reactive is Dead, long live composing side effects.

bit.ly/1sb5hCu

Page 19: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 20: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

In computing, reactive programming is a programming paradigm oriented around data flows and the

propagation of change. This means that it should be possible to express static or dynamic data flows with ease in the programming languages used, and that the

underlying execution model will automatically propagate changes through the data flow.

Page 21: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 22: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Scalable

ResilientReplication

High-Availability

Elasticity

Non-Blocking

Asynchronous

Message-Passing

Isolation

ContainmentLocation-Transparency

Loose-Coupling

Page 23: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Reactive Programming =

Page 24: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

bit.ly/1sb5hCu

Reactive is Dead, long live composing side effects.

Page 25: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

“One thing I’m discovering is that transforming data is easier to think about than

maintaining state.” !

- Dave Thomas

Page 26: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

let y = f(x)

Imperative Functional

x.f()

Page 27: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

mutation

let y = f(x)

Imperative Functional

x.f()

Page 28: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 29: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Move Up

Move Down

Page 30: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

private var arrowKeyUp:Bool; private var arrowKeyDown:Bool; !private var platform1:Platform; private var platform2:Platform; private var ball:Ball;

Page 31: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

function keyDown(event:KeyboardEvent):Void { if (currentGameState == Paused && event.keyCode == 32) { setGameState(Playing); } else if (event.keyCode == 38) { arrowKeyUp = true; } else if (event.keyCode == 40) { arrowKeyDown = true; } }

Page 32: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

function keyUp(event:KeyboardEvent):Void { if (event.keyCode == 38) { arrowKeyUp = false; } else if (event.keyCode == 40) { arrowKeyDown = false; } }

Page 33: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

function everyFrame(event:Event):Void { if(currentGameState == Playing){ if (arrowKeyUp) { platform1.y -= platformSpeed; } if (arrowKeyDown) { platform1.y += platformSpeed; } if (platform1.y < 5) platform1.y = 5; if (platform1.y > 395) platform1.y = 395; } }

Page 34: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

function everyFrame(event:Event):Void { if(currentGameState == Playing){ if (arrowKeyUp) { platform1.y -= platformSpeed; } if (arrowKeyDown) { platform1.y += platformSpeed; } if (platform1.y < 5) platform1.y = 5; if (platform1.y > 395) platform1.y = 395; } }

Page 35: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

source files

state changes

Page 36: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

source files execution

Page 37: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

source files execution

Page 38: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

mental model

input state new state behaviour

{ x; y } { x; y-speed }

{ x; y } { x; y+speed }

timer { x; y } { x; y } draw platform

… … … …

Page 39: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

transformation

let y = f(x)

Imperative Functional

x.f()

Page 40: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Transformations simplify problem decomposition

Page 41: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Move Up

Move Down

Page 42: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input

Page 43: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input

Page 44: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input

Page 45: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

UP { x=0, y=1 } DOWN { x=0, y=-1 } LEFT { x=-1, y=0 } RIGHT { x=1, y=0 }

Page 46: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input

Page 47: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input

Page 48: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input

Page 49: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input

Page 50: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Platform = {x:Int, y:Int} defaultPlatform = {x=5, y=0} !delta = Time.fps 20 input = Signal.sampleOn delta Keyboard.arrows !cap x = max 5 <| min x 395 !p1 : Signal Platform p1 = foldp (\{x, y} s -> {s | y <- cap <| s.y + 5*y}) defaultPlatform input

Page 51: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Rx Dart ElmObservable Stream Signal

= =

Page 52: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 53: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 54: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 55: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Idea See in Action

Page 56: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 57: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 58: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 LambdaCon

Yan Cui (@theburningmonk)my adventure with Elm

Page 59: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

http://bit.ly/1wV46XS

Page 60: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Elm Basics

Page 61: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

add x y = x + y

Page 62: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

add : Int -> Int -> Intadd x y = x + y

Page 63: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

calcAngle start end = let distH = end.x - start.x distV = end.y - start.y in atan2 distV distH

Page 64: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

calcAngle start end = let distH = end.x - start.x distV = end.y - start.y in atan2 distV distH

Page 65: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

calcAngle start end = let distH = end.x - start.x distV = end.y - start.y in atan2 distV distH

Page 66: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

multiply x y = x * y triple = multiply 3

Page 67: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

multiply x y = x * y triple = multiply 3

Page 68: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

f a b c d = … f : Int -> (Int -> (Int -> (Int -> Int)))

Page 69: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

double list = List.map (\x -> x * 2) list

Page 70: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

double list = List.map ((*) 2) list

Page 71: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

tuple1 = (2, “three”) tuple2 = (2, “three”, [4, 5])

Page 72: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

tuple4 = (,) 2 “three” tuple5 = (,,) 2 “three” [4, 5]

Page 73: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

x = { age=42, name=“foo” }

Page 74: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

lightweight, labelled data structure

Page 75: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

x.age x.name

-- 42 -- “foo”

Page 76: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

x.age x.name

-- 42 -- “foo”

.age x

.name x-- 42 -- “foo”

Page 77: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

-- clone and update y = { x | name <- "bar" }

Page 78: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Character = { age : Int, name : String }

Page 79: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type alias Named a = { a | name : String } type alias Aged a = { a | age : Int }

Page 80: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

lady : Named ( Aged { } ) lady = { name=“foo”, age=42 }

Page 81: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

getName : Named x -> String getName { name } = name

Page 82: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

getName : Named x -> String getName { name } = name !

getName lady -- “foo”

Page 83: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type Status = Flying Pos Speed | Exploding Radius | Exploded

Page 84: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

aka. “sums-and-products”

data structures

Page 85: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

type Status = Flying Pos Speed | Exploding Radius | Exploded

sums : choice between variants of a type

Page 86: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

products : tuple of types

type Status = Flying Pos Speed | Exploding Radius | Exploded

Page 87: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)

Page 88: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)

filled : Color -> Shape -> Form

Page 89: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)

Page 90: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y radius = circle radius |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)

Page 91: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

“…a clean design is one that supports visual thinking so people can meet their informational needs with a minimum of

conscious effort.” !

- Daniel Higginbotham (www.visualmess.com)

Page 92: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 93: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y radius = radius |> circle |> filled (rgb 150 170 150) |> alpha 0.5 |> move (x, y)

2. top-to-bottom

1. left-to-right

Page 94: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle : Int -> Int -> Float -> Form

Page 95: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = circle >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)

Page 96: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = circle >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)

circle : Float -> Shape

Page 97: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)

Page 98: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)

filled : Color -> Shape -> Form

Page 99: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)

Curried!

filled : Color -> Shape -> Form

Page 100: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)

Shape -> Form

Page 101: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)

Page 102: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)

Page 103: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)

Page 104: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)

Page 105: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Form) >> alpha 0.5 >> move (x, y)

Page 106: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Form) >> (Form -> Form) >> move (x, y)

Page 107: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Form) >> (Form -> Form) >> move (x, y)

Page 108: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Form) >> move (x, y)

Page 109: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Form) >> (Form -> Form)

Page 110: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Form) >> (Form -> Form)

Page 111: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle x y = (Float -> Form)

Page 112: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

drawCircle : Int -> Int -> (Float -> Form)

Page 113: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

greet name = case name of "Yan" -> “hi, theburningmonk" _ -> “hi, “ ++ name

Page 114: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

greet name = case name of "Yan" -> “hi, theburningmonk" _ -> “hi, “ ++ name

Page 115: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

fizzbuzz n = if | n % 15 == 0 -> "fizz buzz" | n % 3 == 0 -> "fizz" | n % 5 == 0 -> "buzz" | otherwise -> show n

Page 116: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Mouse.position Mouse.clicks

Mouse.isDown …

Page 117: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Window.dimension Window.width Window.height

Page 118: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Time.every Time.fps

Time.timestamp Time.delay

Page 119: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Mouse.position : Signal (Int, Int)

Page 120: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Mouse.position : Signal (Int, Int)

Page 121: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Mouse.position : Signal (Int, Int)

(10, 23) (3, 16) (8, 10) (12, 5) (18, 3)

Page 122: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Keyboard.lastPressed : Signal Int

Page 123: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Keyboard.lastPressed : Signal Int

H E L L O space

Page 124: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Keyboard.lastPressed : Signal Int

H E L L O space

72 69 76 76 79 32

Page 125: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

map : (a -> b) -> Signal a -> Signal b

Page 126: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

<~

Page 127: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Signal of num of pixels in window

Page 128: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

(\(w, h) -> w*h) <~ Window.dimensions

Page 129: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

(\(w, h) -> w*h) <~ Window.dimensions

Signal (Int, Int)(Int, Int) -> Int

Page 130: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

(\(w, h) -> w*h) <~ Window.dimensions

Signal (Int, Int)(Int, Int) -> Int

Signal Int

Page 131: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

(10, 10) (15, 10) (18, 12)

100 150 216

(\(w, h) -> w*h) <~ Window.dimensions

Page 132: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

map2 : (a -> b -> c) -> Signal a -> Signal b -> Signal c

Page 133: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

~

Page 134: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

(,) <~ Window.width ~ Window.height

Signal Int

a -> b -> (a, b)

Signal Int

Page 135: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

(,) <~ Window.width ~ Window.height

Signal Int

Int -> Int -> (Int, Int)

Signal Int

Page 136: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

map3 : (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d

Page 137: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

(,,) <~ signalA ~ signalB ~ signalC

Page 138: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

map4 : … map5 : … map6 : … map7 : … map8 : …

Page 139: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp : (a -> b -> b) -> b -> Signal a -> Signal b

Page 140: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp : (a -> b -> b) -> b -> Signal a -> Signal b

Page 141: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp : (a -> b -> b) -> b -> Signal a -> Signal b

Page 142: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp : (a -> b -> b) -> b -> Signal a -> Signal b

Page 143: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp : (a -> b -> b) -> b -> Signal a -> Signal b

Page 144: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp : (a -> b -> b) -> b -> Signal a -> Signal b

Page 145: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp (\_ n -> n + 1) 0 Mouse.clicks

Page 146: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp (\_ n -> n + 1) 0 Mouse.clicks

Page 147: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

foldp (\_ n -> n + 1) 0 Mouse.clicks

Page 148: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

1 3 42 5

foldp (\_ n -> n + 1) 0 Mouse.clicks

Page 149: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

UP { x=0, y=1 } DOWN { x=0, y=-1 } LEFT { x=-1, y=0 } RIGHT { x=1, y=0 }

Page 150: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

merge : Signal a -> Signal a -> Signal a mergeMany : List (Signal a) -> Signal a …

Page 151: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Js Interop, WebGL

HTML layout, dependency management,

etc.

Page 152: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 153: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

8 segments

Page 154: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

direction

Page 155: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

change

change

no changenot allowed

direction

Page 156: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

direction

Page 157: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

direction

Page 158: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

direction

Page 159: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

direction

Page 160: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

direction

cherry

Page 161: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

direction

YUM YUM YUM!

Page 162: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

direction

+1 segment

Page 163: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 164: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 165: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 LambdaCon

Yan Cui (@theburningmonk)my adventure with Elm

Page 166: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 LambdaCon

Yan Cui (@theburningmonk)my adventure with Elm

Page 167: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 168: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 169: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Demo

Page 170: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 171: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 172: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 173: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 174: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 175: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 176: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 177: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 178: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 179: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 180: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 181: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 182: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 183: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 184: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 185: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 186: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

github.com/theburningmonk/elm-snake

github.com/theburningmonk/elm-missile-command

Missile Command

Snake

Page 187: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

elm-lang.org/try

debug.elm-lang.org/try

Page 188: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

the����������� ������������������  not����������� ������������������  so����������� ������������������  great����������� ������������������  things

Page 189: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Type error between lines 63 and 85: case gameState of

NotStarted -> if | userInput == Space -> Started (defaultSnake,Nothing)

| True -> gameState Started ({segments,direction},cherry) -> let arrow = case userInput

of Arrow arrow -> arrow

_ -> {x = 0, y = 0} newDirection = getNewDirection

arrow direction newHead = getNewSegment

(List.head segments) newDirection newTail = List.take

((List.length segments) - 1) segments

(w,h) = windowDims isGameOver = (List.any

(\t -> t == newHead) newTail) ||

(((fst newHead) > ((toFloat w) / 2)) || (((snd newHead) > ((toFloat h) / 2)) || (((fst newHead) <

((toFloat (-w)) / 2)) || ((snd newHead) <

((toFloat (-h)) / 2))))) in if | isGameOver -> NotStarted

| True -> Started

({segments = newHead :: newTail, direction = newDirection},

cherry) ! Expected Type: {}

Actual Type: Snake.Input

cryptic error messages

Page 190: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

breaking changes

Page 191: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 192: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 193: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 194: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 195: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 196: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 197: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Page 198: My adventure with elm (LambdaCon15)

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

@theburningmonk

github.com/theburningmonk

theburningmonk.com

Page 199: My adventure with elm (LambdaCon15)

Leave your feedback on Joind.in! https://joind.in/13665 !!

BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon