Top Banner
Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges @leonardo_borges www.leonardoborges.com www.thoughtworks.com Friday, 17 May 13
40

Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges

May 31, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Taming asynchronous workflows with Functional Reactive ...€¦ · Taming asynchronous workflows with Functional Reactive Programming LambdaJam - Brisbane, 2013 Leonardo Borges

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

‘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

“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

“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

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

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

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

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

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

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

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

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

(>>=) :: 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

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

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

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

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

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

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

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

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

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

(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

“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

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

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