Philip Roberts: Enemy of the State: An Introduction to Functional Reactive Programming and Bacon.js
Philip Roberts (@philip_roberts) was talking about Functional Reactive Programming at Scotland.js, these are my notes from his talk.
When we are writing JS we are writing realitime code which imples asyncrnous code which implies callbacks which imples calback hell.
Why is callback hell so horrible.
We invert our control flow: it no longer runs top to bottom which makes it hard to understand it.
A pure function is completely self contained. A callback is the complete opposite - it takes input and doesn't return anything.
Typically in jQuery we bind a callback that mutates global state and doesn't return anything. They run on events, not in sequence and often interact with each other and potentially compete. If they are in different parts of our code base they they are hard to debug.
We could represent these as a sequence of events. This sequence can then be manipulated with a pure function that takes input and returns output. The result of this output is then placed in the page.
Bacon.js
Bacon.js provides us with a number of features to help us do this.
Event streams
- We can bind an event to a stream.
- We can map event streams to functions that manipulate the values.
- We can merge event streams into a new event stream that combines them.
- A scanned stream can provide a form of state from a merged stream.
- An assignment can then output the result of the scanned stream to the UI.
Properties
- Like event streams but they hold their current state (e.g. the value of an input field)
FlatMap
Ajax can be pretty hairy as you need to worry about when the response comes back from the server.
For exmple - a user name availability checker.
- Build an event stream of keyup events in the username field.
- An Ajax request is a stream of one value (request -> wait -> result)
- We need a FlatMap: for value on a stream we create a new event stream and then converge them into one stream.
- Requests can still return out of sequence so we can add a filter to the FlatMap which discards earlier responses if a later response has already come in.
Further reading
- Haskell - can't have state.
- RxJS - brought FRP to JS.
- Bacon.js - makes FRP easy to use.