LET IT FLOW 
Introduction to Functional Reactive Programming 
@ArturSkowronski
About Me 
@ArturSkowronski
Functional 
REACTIVE PROGRAMMING
DATAFLOW
PROPAGATION 
OF CHANGE
a = 1 
b = 2 
c = a + b
b = 3 
c = ?
C 
A 
B
Properties 
or 
Signals 
or 
Behaviours
Event Streams
Single Event
Events Stream
Dirty Checking! 
Change Listeners!
Creator: Juha Paananen
Observable 
EventStreams 
Properties
Talk is cheap. Show me the code 
Linus Torvald
Examples
Example 1: ScoreBoard
var score = 0 
$('#plus').click(function(){ 
score = score + 1; 
$('#result').html(score); 
}) 
$('#minus').click(function(){ 
score = score - 1; 
$('#result').html(score); 
})
var plus = $('#plus') 
.asEventStream('click'); 
! 
var minus = $('#minus') 
.asEventStream('click');
var score = plus.map(1) 
.merge(minus.map(-1)) 
.scan(0, function(x, y){ 
return x + y })
Map
var score = plus.map(1) 
.merge(minus.map(-1)) 
.scan(0, function(x, y){ 
return x + y })
var 
.merge(minus.map(-1)) 
.
a 
b 
a.merge(b) 
1 3 
2 
1 2 3 
Merge
var 
. 
.scan(0, function(x, y){ 
return x + y })
Event Stream 
Property
a 
a.scan('',sum) 
"a" 
"c" "t" 
"" "c" "ca" 
"cat" 
Seed Value 
"" + "c" 
"c" + "a" 
"ca" + "t" 
Scan
score.onValue(function(value){ 
$("#score").html(value); 
}); 
Side Effect
var favorite = $('#favorite') 
.asEventStream('click') 
.map(2);
var score = up 
.merge(down) 
.merge(favorite) 
.scan(0, sum)
Example 1I: Combining DataStreams
function inputVal(ev) { 
return $(ev.currentTarget).val() } 
var username = 
$('#username').asEventStream('keyup') 
.map(inputVal) 
Username:
var password = 
$('#password').asEventStream('keyup') 
.map(inputVal) 
Username: 
Password:
Custom Function 
uValid = username.map(isValid) 
! 
! 
pValid = password.map(isValid)
validForm 
= 
uValid.combine(pValid, function(a, b){ 
return a && b 
})
a 
b 
a.combine 
(b, plus) 
1 3 
2 
3 5 
Combine
Submit 
validForm.onValue(function(value) { 
$("#submit").attr("disabled", !enabled) 
})
Example III: Promises
Bacon.fromPromise 
var ajaxCall = Bacon.fromPromise( 
$.ajax({ url : "meetjs/users.json"}) 
) 
var ajaxCall(query){ 
return Bacon.fromPromise( 
$.ajax({ url : "meetjs/?q=" + query})) 
}
Search: 
var search = 
$('#search').asEventStream('keyup') 
.map(inputVal) 
search.map(ajaxCall).onValue(function(value){ 
value.onValue(function(value){ 
doSomethingWithResult(value); 
}); 
});
Search: 
search.map(ajaxCall).onValue(function(value){ 
value.onValue(function(value){ 
doSomethingWithResult(value); 
}); 
});
flatMap
a 
~1 ~2 
f(1) 
f(2) 
"a" 
a.flatMap(f) "a" "b" 
FlatMap 
"b"
a 
~1 ~2 
f(1) 
f(2) 
a.flatMapLatest 
"a" 
(f) "a" 
"b" 
FlatMapLatest
search.flatMapLatest(ajaxCall) 
.onValue(function(value){ 
doSomethingWithResult(value); 
})
WHERE ?
Wrap Up
Filters 
Bus 
Combine 
Templates 
This Presentation
Thank You! 
Questions? 
@ArturSkowronski arturskowronski.com

Let it Flow - Introduction to Functional Reactive Programming