frp_presentation



frp_presentation

3 1


frp_presentation


On Github jmuraski / frp_presentation

Functional Reactive Programming

by Ted Naleid & Joe Muraski

What is reactive programming?

Well…there's a manifesto you can sign

Ask 100 people what ‘reactive programming’ is…

and you'll get a lot of buzzwords and handwaving

So what is functional reactive programming?

In the beginning

Getting a single value (synchronous, blocking)

getUser: User

Easy to use and reason about, but it doesn't scale

Get multiple values (synchronous, blocking)

getUsers: List[User]

Now we get Iterators

(as documented by the Gang of Four)

Composable data manipulation

val adults = users.filter(_.age > 17).sortBy(p => (p.lName, p.fName)).take(10)

but we block until the full list is ready

Callbacks/CPS let us work asynchronously

CPS - Continuation Passing Style

Call Back Hell

show easy then painful examples

Futures/Promises help tame callback hell

(for single values)

get single value (async)

getWidget: Future[Widget]

What if you need a list of items asynchronously?

One way is to request the full list in an asynchronous way:

getWidgets: Future[Widget]

Server calculates list asynchronously and does a callback when it has the full list

Problems: - need to wait for full list to come back (slow user experience) - what if it's infinite (need to paginate, etc) - what if it's a stream that updates? we need to poll for updates

Observer pattern (as documented by the Gang of Four)

lets you register a callback

but then it is up to you to aggregate those into mutable lists and let consumers know that the list has been updated

what if this happened?

You got your Iterator in my Observable! You got your Observable in my Iterator!

Photoshopped Reeses Peanut Butter Cups image

their love child would be the Observable

getWidgets: Observable[Widget]

Allows you to asynchronously get

They are also composable, as we will see

Marble diagrams explanation using something like drop

Merge

Zip

Other functions

Composition of functions

How does this solve problems in the real world?

Netflix example

netflix does this with their video API:

def getVideos(userId: Long): Observable[Map[String, Any]] = 
  videoService.getVideos(userId)
    .take(10)  // take the first 10, then auto-unsubscribe
    .flatMap(video => {
      val metadata = video.getMetaData(video) // async Map
      val bookmark = videoService.getBookmark(video, userId) // async Map
      val rating = videoService.getRating(video, userId) // async Map
      Observable.zip(Observable(List(metadata, bookmark, rating): _*)).map {
        case m :: b :: r :: Nil => Map("id" -> video.id) ++ m ++ b ++ r
      }
  })
//=> Map(id -> 1, rating -> *****, pos -> 1:33, length -> 2h, title -> Gravity)

That method composes 4 separate asynch calls into a List of 10 Maps

Other examples

Demo (shows merge, zip etc)

Other similar tech that addresses the problems

Scala - Actors (Akka)

Go - Goroutines/Channels

Clojure - core.async

Groovy - Reactor

Notice anything in common with those technologies?

Notice anything in common with those technologies?

None of them are in Java, reasoning about asynchronous code is easier in more expressive languages

Questions?