Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows...
Transcript of Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows...
![Page 1: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/1.jpg)
Taming asynchronous workflows with Functional
Reactive ProgrammingLambdaJam - Brisbane, 2013
Leonardo Borges@leonardo_borgeswww.leonardoborges.comwww.thoughtworks.com
Friday, 17 May 13
![Page 2: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/2.jpg)
Leonardo Borges@leonardo_borgeswww.leonardoborges.comwww.thoughtworks.com
• Thoughtworker• Functional Programming enthusiast• Clojure Evangelist• Founder & Organiser of the Sydney Clojure User Group (clj-syd)• World traveller• Fan of Murray’s Beers :)
about:me
Friday, 17 May 13
![Page 3: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/3.jpg)
Functional programmers like programming with values:
a, b, c...
and pure functions:f, g, h...
Friday, 17 May 13
![Page 4: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/4.jpg)
We get new values by applying functions to it
(f a) ;;=> b
Friday, 17 May 13
![Page 5: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/5.jpg)
But that’s hardly useful when we have multiple values
(def vals [a b c])
Friday, 17 May 13
![Page 6: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/6.jpg)
So we use Higher Order Functions
(map f vals)
Friday, 17 May 13
![Page 7: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/7.jpg)
And compose them as we see fit
(-> vals (filter f) (map g) (reduce h))
Friday, 17 May 13
![Page 8: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/8.jpg)
But what if the value isn’t known...yet?
a?Friday, 17 May 13
![Page 9: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/9.jpg)
We make promises
;; thread#1(def a (promise))
;; ...later in the program(f @a) ;;<= blocks thread
;; thread#2(deliver a 10) ;; now thread#1 continues
Friday, 17 May 13
![Page 10: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/10.jpg)
Not great if we want to ‘react’ to a new value
Friday, 17 May 13
![Page 11: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/11.jpg)
What about a list of - as of yet unknown - values?
[a,b,c]? ? ?Friday, 17 May 13
![Page 12: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/12.jpg)
Or better yet, a value that changes over time?
0
37.5
75
112.5
150
10s 20s 30s 40s 50s 60
Val
ue
TimeFriday, 17 May 13
![Page 13: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/13.jpg)
Does this sound familiar?
Friday, 17 May 13
![Page 14: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/14.jpg)
Spreadsheets: a poor man’s reactive programming model
Values
Function
Friday, 17 May 13
![Page 15: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/15.jpg)
Spreadsheets: a poor man’s reactive programming model
As we change a value
Our function cell reacts to the
change
Friday, 17 May 13
![Page 16: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/16.jpg)
‘Changing a value’ is an event
Several events over time form an event stream
Friday, 17 May 13
![Page 17: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/17.jpg)
“Functional Reactive Programming is about effectively processing event streams without
explicitly managing state”- me
Friday, 17 May 13
![Page 18: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/18.jpg)
“FRP is about handling time-varying values like they were
regular values.”- Haskell wiki
Friday, 17 May 13
![Page 19: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/19.jpg)
We’ll use Reactive Extensions (Rx) - but there are many
implementations
Friday, 17 May 13
![Page 20: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/20.jpg)
In Rx, event streams are called Observable sequences
Friday, 17 May 13
![Page 21: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/21.jpg)
Rx 101
(-> (.returnValue js/Rx.Observable 42) (.map #(* % 2)) (.subscribe #(.log js/console %)))
;; 84
Friday, 17 May 13
![Page 22: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/22.jpg)
Rx 101
(-> (.fromArray js/Rx.Observable (clj->js [10 20 30])) (.map #(* % 2)) (.reduce +) (.subscribe #(.log js/console %)))
;; 120
Friday, 17 May 13
![Page 23: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/23.jpg)
Rx 101(defn project-range [n] (.returnValue js/Rx.Observable (range n)))
(-> (.fromArray js/Rx.Observable (clj->js [1 2 3])) (.selectMany project-range) (.subscribe #(.log js/console (clj->js %))))
;; [0];; [0 1];; [0 1 2]
Friday, 17 May 13
![Page 24: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/24.jpg)
Observables are Monads
Friday, 17 May 13
![Page 25: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/25.jpg)
The Monad Type Class
class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
Friday, 17 May 13
![Page 26: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/26.jpg)
Monad functions: return
return :: a -> m a
returnValue :: a -> Observable a
Friday, 17 May 13
![Page 27: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/27.jpg)
(>>=) :: m a -> (a -> m b) -> m b
selectMany :: Observable a -> (a -> Observable b) -> Observable b
Monad functions: >>= (bind)
Friday, 17 May 13
![Page 28: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/28.jpg)
Demo: Simple polling app
Friday, 17 May 13
![Page 29: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/29.jpg)
Server exposes poll questions and results
e.g.:{:id 7 :question "Which is the best music style?" :results {:a 10 :b 47 :c 17}}
Friday, 17 May 13
![Page 30: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/30.jpg)
What we want• Render results• Continuously poll server every 2 secs• If current question is the same as the previous one update results; • Otherwise:• Stop polling;• Display countdown message;• Render new question and results;• Restart polling;
Friday, 17 May 13
![Page 31: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/31.jpg)
The core idea
Friday, 17 May 13
![Page 32: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/32.jpg)
Turn server results into an event stream
112334
Friday, 17 May 13
![Page 33: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/33.jpg)
Duplicate stream, skipping one
112334
123345
skip 1
Friday, 17 May 13
![Page 34: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/34.jpg)
Zip them together112334
1
2
zip
2
3
3
3
3
4
4
5 1
123345
1
Friday, 17 May 13
![Page 35: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/35.jpg)
Now we have access to both the previous and current
results, with no local variables
Friday, 17 May 13
![Page 36: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/36.jpg)
Show me the code!
https://github.com/leonardoborges/frp-codeFriday, 17 May 13
![Page 37: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/37.jpg)
(def results-connectable (let [obs (-> js/Rx.Observable (.interval 2000) (.selectMany results-observable) (.publish) (.refCount)) obs-1 (.skip obs 1)] (.zip obs obs-1 (fn [prev curr] {:prev prev :curr curr}))))
Turn server results into an event stream{
The core idea
Clone stream, skip one
Zip them together {Friday, 17 May 13
![Page 38: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/38.jpg)
“FRP is about handling time-varying values like they were
regular values.”- Haskell wiki
Friday, 17 May 13
![Page 39: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/39.jpg)
Questions?Leonardo Borges
@leonardo_borgeswww.leonardoborges.comwww.thoughtworks.com
Friday, 17 May 13
![Page 40: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges](https://reader030.fdocuments.net/reader030/viewer/2022040411/5edab407c0b4ce3e634eecf8/html5/thumbnails/40.jpg)
ReferencesCode - https://github.com/leonardoborges/frp-code
RxJS - https://github.com/Reactive-Extensions/RxJSRxJava - https://github.com/Netflix/RxJava
Other FRP implementations:Reactive-banana - http://www.haskell.org/haskellwiki/Reactive-bananaJavelin (Clojurescript) - https://github.com/tailrecursion/javelinBacon.js - https://github.com/raimohanska/bacon.js
Friday, 17 May 13