What is Functional Reactive Programming?

Functional Reactive Programming enables a much simpler way to deal with events. With Bacon JS, events are seperate from the views and models as a stream of values in time. These streams can be thought of as lists of values that can then be mapped to transformation functions that model the data before passing to the views to render. This requires a different mindset to the typical imperative style of UI programming as rather than mutating the state throughout the code, changes are represented as new state objects that are passed down through the views.

A very simple example of this relationship between events and state is an event stream that listens to clicks and maps each click to the value 1. The resulting list (or stream) of 1s at each point in time that the event is fired, can then be reduced with a Bacon JS scan function to add them all together, thereby resulting in a state representing the number of times something has been clicked.

// The value from the event stream can be thought of as a list:
eventStream = []

// As the events come in (for instance an 'Add 1' button is clicked), 1 is added to the list
eventStream = [1] // Click!
eventStream = [1, 1] // Click!

// The values can be reduced by adding the individual items together:
eventStream = [1, 1, 1] // = 3
eventStream = [1, 1, 1, 1] // = 4
eventStream = [1, 1, 1, 1, 1] // = 5

The benefits of this may not be immediately apparent, but this can greatly simplify your asynchronous code by composing pure functions around the values from the event stream in a very easy to read manner, rather than chaining callbacks together (that can become very difficult to maintain) and mutating the state of variables (leading to side effects that can produce unexpected bugs).

I highly advise watching the following presentation by Phillip Roberts to help gain a clearer insight:

When is it useful

Functional Reactive Programming is useful in almost any case that deals with realtime, event driven behaviour. Examples of this would be computer games (like the classic ‘Snake’ game) realtime charts, spreadsheets, and could also be handy on the server side for background processes.

What is BaconJS?

Bacon JS is a library for Javascript that provides methods like merge, combine, and flatMapLatest for handling multiple event streams, and functions like map and filter for transforming and filtering the streams.

Simple Example

Below I’ve adapted the simple plus/minus demo from the Bacon JS Docs to include key presses as additional event streams, and tied it in with the time based visual that Phillip Roberts used in his talk:


Note that you can also add and subtract using the + and - keys..

Plus Stream

Minus Stream

Merged Stream

Scan Stream


<!DOCTYPE html>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/bacon.js/0.7.10/bacon.min.js"></script>
<button id="plus">Plus</button>
<button id="minus">Minus</button>
<div id="counter"></div>


var click_plus,
all_key_downs = jQuery(document).asEventStream('keydown'),

// Click Events
click_plus = jQuery('# plus').asEventStream('click');
click_minus = jQuery('# minus').asEventStream('click');

// Key Events
key_plus = all_key_downs.filter(function (e) { return e.keyCode === 187 && e.shiftKey; });
key_minus = all_key_downs.filter(function (e) { return e.keyCode === 189 && e.shiftKey; });

counter = click_plus
.map(1) // Map click_plus to 1
.merge(key_plus.map(1)) // Map key_minus to -1
.merge(click_minus.map(-1)) // Map click_minus to -1
.merge(key_minus.map(-1)) // Map key_minus to -1
.scan(0, function (x, y) { return x + y; });

// Assign the result of variable counter to dom element with class of 'counter'
counter.assign(jQuery('# counter'), 'text');