Fairmont/Reactive
Fairmont/Reactive is a JavaScript library for functional reactive programming.
Here's a simple 'hello, world' Web server written in a functional, reactive style using Fairmont.
In JavaScript
start(flow([
events("request", server),
select(spread(function(request) {
return request.method === "GET";
})),
select(spread(function(request) {
return request.url === "/";
})),
tee(spread(function(ignored, response) {
response.statusCode = 200;
response.write("hello, world");
response.end();
})),
map(spread(logger));
]));
In CoffeeScript
start flow [
events "request", server
select spread (request) -> request.method == "GET"
select spread (request) -> request.url == "/"
tee spread (ignored, response) ->
response.statusCode = 200
response.write "hello, world"
response.end()
map spread logger
]
Examples
You can get a feel for what Fairmont can do for you by checking out the examples.
Introduction
Iterators
An iterator is an ES6 iterator, with a next
function that produces a value wrapper.
A value wrapper is what iterators produce, with done
and value
properties.
These are part of the ES6 standard.
Reactors
An asynchronous iterator is an iterator that produces promises that resolve to value wrappers.
These are a proposed part of ES7.
An asynchronous iterator function is a function that returns promises that resolve to value wrappers.
A reactor is Fairmont lingo for an asynchronous iterator.
When talking about values that could be iterators or reactors, we will sometimes say producers.
Adapters, Filters, and Reducers
An adapter creates a producer (an iterator or reactor) from a non-producer.
An iterator filter is a function that takes an iterator and returns another iterator.
Iterator filters are just called filters for convenience whenever it isn't ambiguous.
An iterator reducer is a function that takes an iterator and returns a value that isn't an iterator.
Iterator reducers are just called reducers for convenience whenever it isn't ambiguous.
When talking about functions that could be adapters, filters, or reducers, we will sometimes say transforms.
Polymorphic Filters And Reducers
Most transforms are implemented for both iterators and reactors.
For example, if we pass an iterator to map
we'll get back an iterator. Whereas if we pass it a reactor, we'll get back a reactor.
Similarly, if we pass an iterator to collect
we'll get back an array.
If we pass it a reactor, we'll get back a promise that resolves to an array.
Many values that aren't iterators or reactors will be coerced into one or the other when passed to a transform or reduction.
For example, if you pass an array into map
, the array will be coerced into an iterator.
Similarly, if you pass a promise into map
, the promise will be coerced into a reactor.
About Fairmont
Fairmont takes full advantage of ES6+ features like iterators (including async iterators, called reactors), generators, and promises. Inspired by libraries like Underscore and many others, Fairmont features include:
- reactive programming support through async iterators
- lazy evaluation on collection operations via iterators
- core functional operations, like currying and composition
- bridge functions for integrating with OOP-based libraries
- common file and stream based operations
- streams and event emitters modeled as reactors
- seamless integration between synchronous and asynchronous operations
- … and more!
Status
Fairmont is still under heavy development and is beta
quality, meaning you should probably not use it in your production code.
Roadmap
You can get an idea of what we're planning by looking at the issues list. If you want something that isn't there, and you think it would be a good addition, please open a ticket.