Slide 1

Slide 1 text

Promise of a Better Future Rahul Goma Phulore (@missingfaktor) XConf Manchester, 2015.07.09

Slide 2

Slide 2 text

About me • Ex-ThoughtWorker (Pune, India) • Backend Engineer at SoundCloud (Berlin, Germany) • Functional programming practitioner since 
 5+ years

Slide 3

Slide 3 text

Thesis Concurrency is hard. Necessarily so. However our tools make it harder than it has to be. Promises and futures is a concurrency abstraction that cater to many common use cases for concurrency, and make writing correct and concurrent software easier.

Slide 4

Slide 4 text

What are futures? • A proxy to a value that might be available at some point in time. • A value of type Future[Int] is a proxy to a value of type Int. • Some implementations separate promises and futures, some don’t.

Slide 5

Slide 5 text

What are futures? • Futures are multiplexed onto threads. You can have hundreds of thousands of futures with just a handful of threads! • The thread pools are typically configured separately. • We do not block current thread while waiting for a result of another future.

Slide 6

Slide 6 text

Running Example • Given a facebook page, grab likes for all the posts on that page. • If there is an error, log it and return an empty sequence.

Slide 7

Slide 7 text

#1 No Concurrency

Slide 8

Slide 8 text

CODE

Slide 9

Slide 9 text

✴ Pros ✴ Simple code ✴ Cons ✴ No concurrency :(

Slide 10

Slide 10 text

#2 Java style futures

Slide 11

Slide 11 text

CODE

Slide 12

Slide 12 text

✴ Pros ✴ Some concurrency ✴ Cons ✴ …still not nearly enough ✴ Doesn’t scale easily for more complex cases

Slide 13

Slide 13 text

#2 Callbacks

Slide 14

Slide 14 text

CODE

Slide 15

Slide 15 text

✴ Pros ✴ Concurrency. Yay! ✴ Cons ✴ “Inverted” APIs ✴ Requires a lot of hand-coordination. Control flow needs to be dictated. ✴ Doesn’t scale easily for more complex cases. ✴ Error handling is complex.

Slide 16

Slide 16 text

#3 "Functional" futures

Slide 17

Slide 17 text

CODE

Slide 18

Slide 18 text

✴ Pros ✴ Retains pretty much the same shape as the original non- concurrent code. ✴ Invisible, except when it shouldn't be. ✴ Computations expressed as data dependencies, rather than with complex control flow. ✴ Error handling is smooth. ✴ Scales easily. ✴ Cons ✴ … We'll come to that!

Slide 19

Slide 19 text

Callbacks vs functional futures

Slide 20

Slide 20 text

https://goo.gl/CSkVZI

Slide 21

Slide 21 text

"I hope to dismiss the misunderstanding that promises are about having cleaner syntax for callback-based async work. They are about modelling your problem in a fundamentally different way; they go deeper than syntax and actually change the way you solve problems at a semantic level."

Slide 22

Slide 22 text

// Plain old blocking API readFile :: String -> (Buffer | Error) // Callback-based API readFile :: String -> (Error -> Buffer -> ()) -> () // Future-based API readFile :: String -> Future (Buffer | Error) Types

Slide 23

Slide 23 text

// Plain old blocking code: (=) :: a -> (a -> b) -> b map :: Seq a -> (a -> b) -> Seq b tryCatch :: (() -> a) -> (() -> a) -> a filter :: Seq a -> (a -> Bool) -> Seq a // Future-based code: (<-) :: Future a -> (a -> Future b) -> Future b traverse :: Seq a -> (a -> Future b) -> Future (Seq b) recover :: Future a -> (() -> a) -> Future a filterF :: Seq a -> (a -> Future Bool) -> Future (Seq a) Types

Slide 24

Slide 24 text

Still not a silver bullet • Interactions with thread-unsafe libraries. • ThreadLocal variables. • Complex co-ordination not very natural. • Simpler than other concurrency models, but still some cognitive cost. Could be better. • Not suitable for all sorts of concurrency scenarios.

Slide 25

Slide 25 text

Thank You! ☺