SlideShare una empresa de Scribd logo
1 de 199
Descargar para leer sin conexión
BOLOGNA 28 march 2015 LambdaCon
Yan Cui (@theburningmonk)
my adventure with Elm
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
agenda
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Hi, my name isYan Cui.
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
I’m not an expert on Elm.
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Function Reactive
Programming?
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Value over Time
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Time
Value
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Time
Value
Signal
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
?
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
SignalVariable
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Reactive is Dead,	

long live composing side effects.
bit.ly/1sb5hCu
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
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.
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Scalable
ResilientReplication
High-Availability
Elasticity
Non-Blocking
Asynchronous
Message-Passing
Isolation
Containment
Location-Transparency
Loose-Coupling
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Reactive Programming =
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
bit.ly/1sb5hCu
Reactive is Dead,	

long live composing side effects.
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
let y = f(x)
Imperative Functional
x.f()
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
mutation
let y = f(x)
Imperative Functional
x.f()
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Move Up
Move Down
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;
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;
	

 }	

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

 }	

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

	

 }	

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

 }	

}
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
source files
state changes
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
source files execution
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
source files execution
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
… … … …
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
transformation
let y = f(x)
Imperative Functional
x.f()
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Transformations
simplify problem
decomposition
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Move Up
Move Down
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
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
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
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 }
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
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
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
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
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Rx Dart Elm
Observable Stream Signal
= =
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Idea See in Action
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 LambdaCon
Yan Cui (@theburningmonk)
my adventure with Elm
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
http://bit.ly/1wV46XS
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Elm Basics
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
add x y = x + y
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
add : Int -> Int -> Int
add x y = x + y
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
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
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
multiply x y	

= x * y	

triple = multiply 3
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
multiply x y	

= x * y	

triple = multiply 3
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
f a b c d = …	

f :	

 Int -> 	

	

 	

 	

 (Int -> 	

	

 	

 	

 	

 (Int -> 	

	

 	

 	

 	

 	

 (Int -> Int)))
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
double list = List.map (x -> x * 2) list
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
double list = List.map ((*) 2) list
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
tuple1 = (2,“three”)	

tuple2 = (2,“three”, [4, 5])
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
tuple4 = (,) 2 “three”	

tuple5 = (,,) 2 “three” [4, 5]
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
x = { age=42, name=“foo” }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
lightweight, labelled
data structure
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
x.age	

x.name
-- 42	

-- “foo”
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
x.age	

x.name
-- 42	

-- “foo”
.age x	

.name x
-- 42	

-- “foo”
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
-- clone and update	

y = { x | name <- "bar" }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
type alias Character = 	

{ age : Int, name : String }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
type alias Named a = { a | name : String }	

type alias Aged a = { a | age : Int }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
lady : Named ( Aged { } )	

lady = { name=“foo”, age=42 }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
getName : Named x -> String	

getName { name } = name
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
getName : Named x -> String	

getName { name } = name	

!
getName lady	

	

 -- “foo”
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
type Status = Flying Pos Speed	

	

 	

 	

 	

 	

 	

 	

 | Exploding Radius	

	

 	

 	

 	

 	

 	

 	

 | Exploded
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
aka.	

“sums-and-products”	

data structures
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
type Status = Flying Pos Speed	

	

 	

 	

 	

 	

 	

 | Exploding Radius	

	

 	

 	

 	

 	

 	

 | Exploded
sums : 	

choice between variants of a type
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
products : 	

tuple of types
type Status = Flying Pos Speed	

	

 	

 	

 	

 	

 	

 | Exploding Radius	

	

 	

 	

 	

 	

 	

 | Exploded
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)
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
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)
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)
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)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle : Int -> Int -> Float -> Form
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 circle 	

	

>> filled (rgb 150 170 150)	

	

>> alpha 0.5	

	

>> move (x, y)
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> filled (rgb 150 170 150)	

	

>> alpha 0.5	

	

>> move (x, y)
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
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
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> (Shape -> Form)	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> (Shape -> Form) 	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> (Shape -> Form) 	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Shape) 	

	

>> (Shape -> Form) 	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> alpha 0.5	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> (Form -> Form)	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> (Form -> Form)	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> move (x, y)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> (Form -> Form)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)	

	

>> (Form -> Form)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle x y =	

	

 (Float -> Form)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
drawCircle : Int -> Int -> (Float -> Form)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
greet name =	

case name of 	

"Yan" 	

-> “hi, theburningmonk"	

_ 	

	

 -> “hi,“ ++ name
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
greet name =	

case name of 	

"Yan" 	

-> “hi, theburningmonk"	

_ 	

	

 -> “hi,“ ++ name
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Mouse.position	

Mouse.clicks	

Mouse.isDown	

…
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Window.dimension	

Window.width	

Window.height
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Time.every	

Time.fps	

Time.timestamp	

Time.delay	

…
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Mouse.position : Signal (Int, Int)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Mouse.position : Signal (Int, Int)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Mouse.position : Signal (Int, Int)
(10, 23) (3, 16) (8, 10) (12, 5) (18, 3)
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Keyboard.lastPressed : Signal Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Keyboard.lastPressed : Signal Int
H E L L O space
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Keyboard.lastPressed : Signal Int
H E L L O space
72 69 76 76 79 32
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
map : (a -> b) -> Signal a -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
<~
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Signal of num of pixels in window
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
((w, h) -> w*h) <~ Window.dimensions
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
((w, h) -> w*h) <~ Window.dimensions
Signal (Int, Int)(Int, Int) -> Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
((w, h) -> w*h) <~ Window.dimensions
Signal (Int, Int)(Int, Int) -> Int
Signal Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
(10, 10) (15, 10) (18, 12)
100 150 216
((w, h) -> w*h) <~ Window.dimensions
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
map2 : (a -> b -> c) 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b 	

	

 	

 	

 	

 -> Signal c
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
~
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
(,) <~ Window.width ~ Window.height
Signal Int
a -> b -> (a, b)
Signal Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
(,) <~ Window.width ~ Window.height
Signal Int
Int -> Int -> (Int, Int)
Signal Int
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
map3 : (a -> b -> c -> d) 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b 	

	

 	

 	

 	

 -> Signal c	

	

 	

 	

 	

 -> Signal d
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
(,,) <~ signalA ~ signalB ~ signalC
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
map4 : …	

map5 : …	

map6 : …	

map7 : …	

map8 : …
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b
	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b
	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 -> b 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp : (a -> b -> b) 	

	

 	

 	

 	

 -> b 	

	

 	

 	

 	

 -> Signal a 	

	

 	

 	

 	

 -> Signal b
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp (_ n -> n + 1) 0 Mouse.clicks
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp (_ n -> n + 1) 0 Mouse.clicks
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
foldp (_ n -> n + 1) 0 Mouse.clicks
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
1 3 42 5
foldp (_ n -> n + 1) 0 Mouse.clicks
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 }
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
merge	

 : Signal a -> Signal a -> Signal a	

mergeMany : List (Signal a) -> Signal a	

…
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Js Interop,
WebGL
HTML layout,
dependency management,
etc.
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
8 segments
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
change
change
no changenot allowed
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
cherry
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
YUMYUMYUM!
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
direction
+1 segment
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 LambdaCon
Yan Cui (@theburningmonk)
my adventure with Elm
BOLOGNA 28 march 2015 LambdaCon
Yan Cui (@theburningmonk)
my adventure with Elm
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
Demo
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
github.com/theburningmonk/elm-snake
github.com/theburningmonk/elm-missile-
command
Missile Command
Snake
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
elm-lang.org/try
debug.elm-lang.org/try
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
the
 not
 so
 great
 things
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
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
breaking changes
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon

Más contenido relacionado

Más de Yan Cui

How to choose the right messaging service for your workload
How to choose the right messaging service for your workloadHow to choose the right messaging service for your workload
How to choose the right messaging service for your workloadYan Cui
 
Patterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdfPatterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdfYan Cui
 
Lambda and DynamoDB best practices
Lambda and DynamoDB best practicesLambda and DynamoDB best practices
Lambda and DynamoDB best practicesYan Cui
 
Lessons from running AppSync in prod
Lessons from running AppSync in prodLessons from running AppSync in prod
Lessons from running AppSync in prodYan Cui
 
Serverless observability - a hero's perspective
Serverless observability - a hero's perspectiveServerless observability - a hero's perspective
Serverless observability - a hero's perspectiveYan Cui
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functionsYan Cui
 
How serverless changes the cost paradigm
How serverless changes the cost paradigmHow serverless changes the cost paradigm
How serverless changes the cost paradigmYan Cui
 
Why your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncWhy your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncYan Cui
 
Build social network in 4 weeks
Build social network in 4 weeksBuild social network in 4 weeks
Build social network in 4 weeksYan Cui
 
Patterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applicationsPatterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applicationsYan Cui
 
How to bring chaos engineering to serverless
How to bring chaos engineering to serverlessHow to bring chaos engineering to serverless
How to bring chaos engineering to serverlessYan Cui
 
Migrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsMigrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsYan Cui
 
Building a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQLBuilding a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQLYan Cui
 
FinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economyFinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economyYan Cui
 
How to improve lambda cold starts
How to improve lambda cold startsHow to improve lambda cold starts
How to improve lambda cold startsYan Cui
 
What can you do with lambda in 2020
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020Yan Cui
 
A chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage awayA chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage awayYan Cui
 
How to debug slow lambda response times
How to debug slow lambda response timesHow to debug slow lambda response times
How to debug slow lambda response timesYan Cui
 
What can you do with lambda in 2020
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020Yan Cui
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functionsYan Cui
 

Más de Yan Cui (20)

How to choose the right messaging service for your workload
How to choose the right messaging service for your workloadHow to choose the right messaging service for your workload
How to choose the right messaging service for your workload
 
Patterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdfPatterns and practices for building resilient serverless applications.pdf
Patterns and practices for building resilient serverless applications.pdf
 
Lambda and DynamoDB best practices
Lambda and DynamoDB best practicesLambda and DynamoDB best practices
Lambda and DynamoDB best practices
 
Lessons from running AppSync in prod
Lessons from running AppSync in prodLessons from running AppSync in prod
Lessons from running AppSync in prod
 
Serverless observability - a hero's perspective
Serverless observability - a hero's perspectiveServerless observability - a hero's perspective
Serverless observability - a hero's perspective
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functions
 
How serverless changes the cost paradigm
How serverless changes the cost paradigmHow serverless changes the cost paradigm
How serverless changes the cost paradigm
 
Why your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncWhy your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSync
 
Build social network in 4 weeks
Build social network in 4 weeksBuild social network in 4 weeks
Build social network in 4 weeks
 
Patterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applicationsPatterns and practices for building resilient serverless applications
Patterns and practices for building resilient serverless applications
 
How to bring chaos engineering to serverless
How to bring chaos engineering to serverlessHow to bring chaos engineering to serverless
How to bring chaos engineering to serverless
 
Migrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 stepsMigrating existing monolith to serverless in 8 steps
Migrating existing monolith to serverless in 8 steps
 
Building a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQLBuilding a social network in under 4 weeks with Serverless and GraphQL
Building a social network in under 4 weeks with Serverless and GraphQL
 
FinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economyFinDev as a business advantage in the post covid19 economy
FinDev as a business advantage in the post covid19 economy
 
How to improve lambda cold starts
How to improve lambda cold startsHow to improve lambda cold starts
How to improve lambda cold starts
 
What can you do with lambda in 2020
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020
 
A chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage awayA chaos experiment a day, keeping the outage away
A chaos experiment a day, keeping the outage away
 
How to debug slow lambda response times
How to debug slow lambda response timesHow to debug slow lambda response times
How to debug slow lambda response times
 
What can you do with lambda in 2020
What can you do with lambda in 2020What can you do with lambda in 2020
What can you do with lambda in 2020
 
How to ship customer value faster with step functions
How to ship customer value faster with step functionsHow to ship customer value faster with step functions
How to ship customer value faster with step functions
 

Último

Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 

Último (20)

Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 

My adventure with elm (LambdaCon15)

  • 1. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  • 2. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon agenda
  • 3. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Hi, my name isYan Cui.
  • 4. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 5. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon I’m not an expert on Elm.
  • 6. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 7. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Function Reactive Programming?
  • 8. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Value over Time
  • 9. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time Value
  • 10. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time Value Signal
  • 11. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 12. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ?
  • 13. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 14. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 15. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon SignalVariable
  • 16. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 17. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 18. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Reactive is Dead, long live composing side effects. bit.ly/1sb5hCu
  • 19. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 20. 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.
  • 21. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 22. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Scalable ResilientReplication High-Availability Elasticity Non-Blocking Asynchronous Message-Passing Isolation Containment Location-Transparency Loose-Coupling
  • 23. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Reactive Programming =
  • 24. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon bit.ly/1sb5hCu Reactive is Dead, long live composing side effects.
  • 25. 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
  • 26. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon let y = f(x) Imperative Functional x.f()
  • 27. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon mutation let y = f(x) Imperative Functional x.f()
  • 28. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 29. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Move Up Move Down
  • 30. 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;
  • 31. 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; } }
  • 32. 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; } }
  • 33. 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; } }
  • 34. 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; } }
  • 35. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files state changes
  • 36. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files execution
  • 37. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon source files execution
  • 38. 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 … … … …
  • 39. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon transformation let y = f(x) Imperative Functional x.f()
  • 40. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Transformations simplify problem decomposition
  • 41. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Move Up Move Down
  • 42. 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
  • 43. 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
  • 44. 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
  • 45. 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 }
  • 46. 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
  • 47. 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
  • 48. 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
  • 49. 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
  • 50. 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
  • 51. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Rx Dart Elm Observable Stream Signal = =
  • 52. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 53. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 54. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 55. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Idea See in Action
  • 56. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 57. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 58. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  • 59. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon http://bit.ly/1wV46XS
  • 60. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Elm Basics
  • 61. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon add x y = x + y
  • 62. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon add : Int -> Int -> Int add x y = x + y
  • 63. 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
  • 64. 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
  • 65. 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
  • 66. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon multiply x y = x * y triple = multiply 3
  • 67. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon multiply x y = x * y triple = multiply 3
  • 68. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon f a b c d = … f : Int -> (Int -> (Int -> (Int -> Int)))
  • 69. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon double list = List.map (x -> x * 2) list
  • 70. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon double list = List.map ((*) 2) list
  • 71. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon tuple1 = (2,“three”) tuple2 = (2,“three”, [4, 5])
  • 72. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon tuple4 = (,) 2 “three” tuple5 = (,,) 2 “three” [4, 5]
  • 73. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x = { age=42, name=“foo” }
  • 74. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon lightweight, labelled data structure
  • 75. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x.age x.name -- 42 -- “foo”
  • 76. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon x.age x.name -- 42 -- “foo” .age x .name x -- 42 -- “foo”
  • 77. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon -- clone and update y = { x | name <- "bar" }
  • 78. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Character = { age : Int, name : String }
  • 79. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type alias Named a = { a | name : String } type alias Aged a = { a | age : Int }
  • 80. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon lady : Named ( Aged { } ) lady = { name=“foo”, age=42 }
  • 81. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon getName : Named x -> String getName { name } = name
  • 82. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon getName : Named x -> String getName { name } = name ! getName lady -- “foo”
  • 83. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type Status = Flying Pos Speed | Exploding Radius | Exploded
  • 84. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon aka. “sums-and-products” data structures
  • 85. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon type Status = Flying Pos Speed | Exploding Radius | Exploded sums : choice between variants of a type
  • 86. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon products : tuple of types type Status = Flying Pos Speed | Exploding Radius | Exploded
  • 87. 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)
  • 88. 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
  • 89. 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)
  • 90. 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)
  • 91. 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)
  • 92. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 93. 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
  • 94. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle : Int -> Int -> Float -> Form
  • 95. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = circle >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)
  • 96. 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
  • 97. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> filled (rgb 150 170 150) >> alpha 0.5 >> move (x, y)
  • 98. 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
  • 99. 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
  • 100. 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
  • 101. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  • 102. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  • 103. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  • 104. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Shape) >> (Shape -> Form) >> alpha 0.5 >> move (x, y)
  • 105. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> alpha 0.5 >> move (x, y)
  • 106. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form) >> move (x, y)
  • 107. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form) >> move (x, y)
  • 108. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> move (x, y)
  • 109. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form)
  • 110. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form) >> (Form -> Form)
  • 111. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle x y = (Float -> Form)
  • 112. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon drawCircle : Int -> Int -> (Float -> Form)
  • 113. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon greet name = case name of "Yan" -> “hi, theburningmonk" _ -> “hi,“ ++ name
  • 114. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon greet name = case name of "Yan" -> “hi, theburningmonk" _ -> “hi,“ ++ name
  • 115. 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
  • 116. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position Mouse.clicks Mouse.isDown …
  • 117. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Window.dimension Window.width Window.height
  • 118. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Time.every Time.fps Time.timestamp Time.delay …
  • 119. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position : Signal (Int, Int)
  • 120. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position : Signal (Int, Int)
  • 121. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Mouse.position : Signal (Int, Int) (10, 23) (3, 16) (8, 10) (12, 5) (18, 3)
  • 122. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Keyboard.lastPressed : Signal Int
  • 123. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Keyboard.lastPressed : Signal Int H E L L O space
  • 124. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Keyboard.lastPressed : Signal Int H E L L O space 72 69 76 76 79 32
  • 125. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map : (a -> b) -> Signal a -> Signal b
  • 126. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon <~
  • 127. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Signal of num of pixels in window
  • 128. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions
  • 129. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions Signal (Int, Int)(Int, Int) -> Int
  • 130. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ((w, h) -> w*h) <~ Window.dimensions Signal (Int, Int)(Int, Int) -> Int Signal Int
  • 131. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (10, 10) (15, 10) (18, 12) 100 150 216 ((w, h) -> w*h) <~ Window.dimensions
  • 132. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map2 : (a -> b -> c) -> Signal a -> Signal b -> Signal c
  • 133. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon ~
  • 134. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,) <~ Window.width ~ Window.height Signal Int a -> b -> (a, b) Signal Int
  • 135. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,) <~ Window.width ~ Window.height Signal Int Int -> Int -> (Int, Int) Signal Int
  • 136. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map3 : (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
  • 137. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon (,,) <~ signalA ~ signalB ~ signalC
  • 138. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon map4 : … map5 : … map6 : … map7 : … map8 : …
  • 139. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 140. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 141. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 142. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 143. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 144. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp : (a -> b -> b) -> b -> Signal a -> Signal b
  • 145. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  • 146. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  • 147. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon foldp (_ n -> n + 1) 0 Mouse.clicks
  • 148. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon 1 3 42 5 foldp (_ n -> n + 1) 0 Mouse.clicks
  • 149. 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 }
  • 150. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon merge : Signal a -> Signal a -> Signal a mergeMany : List (Signal a) -> Signal a …
  • 151. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Js Interop, WebGL HTML layout, dependency management, etc.
  • 152. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 153. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon 8 segments
  • 154. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 155. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon change change no changenot allowed direction
  • 156. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 157. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 158. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 159. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction
  • 160. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction cherry
  • 161. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction YUMYUMYUM!
  • 162. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon direction +1 segment
  • 163. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 164. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 165. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  • 166. BOLOGNA 28 march 2015 LambdaCon Yan Cui (@theburningmonk) my adventure with Elm
  • 167. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 168. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 169. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon Demo
  • 170. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 171. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 172. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 173. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 174. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 175. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 176. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 177. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 178. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 179. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 180. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 181. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 182. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 183. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 184. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 185. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 186. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon github.com/theburningmonk/elm-snake github.com/theburningmonk/elm-missile- command Missile Command Snake
  • 187. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon elm-lang.org/try debug.elm-lang.org/try
  • 188. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon the
  • 189.  not
  • 190.  so
  • 193. 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
  • 194. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon breaking changes
  • 195. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 196. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 197. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 198. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 199. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 200. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 201. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon
  • 202. BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon @theburningmonk github.com/theburningmonk theburningmonk.com
  • 203. Leave your feedback on Joind.in! https://joind.in/13665 ! ! BOLOGNA 28 march 2015 - Yan Cui @theburningmonk LambdaCon