Cycle.js

A fully functional and reactive
JavaScript framework for cleaner code
Why yet another framework?
Something needs to change in the way we build systems.


- Horrendous complexity
- Too much code in HTML
- Inconsistent and surprising behaviour
- Monolithic
- No clear way to separate concerns
- Too much wiring - low signal-to-noise ratio
- A lot of very complex middleware that's difficult to make
- Async is a pain
- Too verbose in some places and too implicit in others
AngularJS
React
We need something better.
Or, at the very least, something different!

Introducing...
A better way
(conveniently also the central idea of Cycle.js)
Functional
Reactive
Programming
What is FRP?
FRP is the culmination of Functional and Reactive Programing to achieve a more explicit dataflow with less magic and more
conciseness.
It helps you make your code cleaner and more understandable with very cohesive, decoupled units that are composable and testable.
Yeah, that was vague...
Let's go one principle at a time
Functional
A way to make programs focusing on small, reusable functions.
Three core pillars:
Pure Functions
Composing Functions
Higher-order Functions
Pure Functions
- Do not use anything outside of their inputs
- Will give you only one output for one set of inputs.
// PURE.
// Only operates on inputs.
// Does not modify external state.
// One input will give you only one output.
function sum(x, y) {
return x + y;
}
// IMPURE.
// Console defined elsewhere
// - doesn't operate on only inputs.
// Has a side effect on the console.
function log(thing) {
console.log(thing);
}
// IMPURE.
// Doesn't operate on only inputs.
// Modifies external state.
function getNetwork() {
// ... doing things with network
// (HTTP requests, etc)
}
// IMPURE.
// One input may give you many
// different outputs.
function silly(number) {
if (Math.random() > 0.5)
return number - 1;
return number;
}
- Do not modify external state or cause anything to happen to the external world.
Pure functions, generally, make it easier to understand, test, and reason about your code, because of the less wiring involved in using them.
Few examples
Composing Functions
Composing functions is a technique to build bigger chunks of behavior from smaller chunks.
let isEven = (x) => x % 2 == 0;
let not = (val) = !val;
let isOdd = (x) = not(isEven(x))
Higher-order Functions
Higher-order functions
are functions that can take functions as parameters.
// Takes a list and returns a new list with
// the given function applied to each of them
function map(func, list) {
let result = [];
for (val of list) {
result.push(val);
}
return result;
}
// Returns a list of values from the given list
// that the given function returns "true" for.
function filter(shouldInclude, list) {
let result = [];
for (val of list) {
if (shouldInclude(val))
result.push(val);
}
return result;
}
let evenSquaresOfOneDigits =
map(x => x * x,
filter(x => x % 2 == 0,
[1, 2, 3, 4, 5, 6, 7, 8, 9]));
You can use them in many ways.
Higher-order functions allow you to think of behavior as a series of transformations to data.
Functional programming emphasizes
-
Small
-
Pure
-
Reusable
That covers functional, now let's look at reactive
Reactive
A way to easily decouple functions
from each other and make any dependencies more clear.
Proactive vs Reactive
a
c
b
"Others define when I should change"
a
c
b
"I define when I change, and due to what"
"Hey, set yourself to this value."
"Hey, this is my new value."
"OK"
"I can do whatever I want with it."
How do you accomplish this?
Event emmiters
- No intuitive way to apply transformations events
- Have to maintain internal state about who to notify
- No way to handle errors
Streams of events
- Can transform events using higher-order functions
- Can simply be returned as any old value from any function
- Can emit errors
What are Streams?
Streams are collections, just like arrays...
Arrays
memory
1
2
3
...but they're spread over time, not memory
Streams
time
click!
click!
click!
Some operations which streams support
- Map
Takes a stream of values, applies a given function to each of those values, and returns a stream with the new values.
- Filter
Takes a stream of values, and returns a stream that only includes values that a given function returns true for.
- Fold
Takes a stream of values, and creates a new stream that emits acculamated values according to a given function.
- Flatten
Takes a stream of streams, and "flattens" them into one stream that emits values from all the emitted streams.
Cycle.js is a fusion of functional and reactive programming that allows you to have the best of both worlds.
Cycle.js allows you to write your entire app as a pure function, bringing the advantages of functional programming with it.
This function, called main(), transforms (using higher-order functions) streams of inputs from the outside world to streams of outputs to the outside world.
Because your app is a pure function, you can split it up into more pure functions that each only transform input streams (sources) to output streams (sinks)
And then you can compose them, because they behave like literally any old function!

Sources are streams of inputs
from the outside world.
(User clicks, HTTP responses, really anything)
Sinks are streams of output
to the outside world.
(Rendered page, HTTP requests, again anything)
The outside world is represented by what are known as drivers. These are the impure functions, the only place where your code touches the external world.
They take in sinks from the main function, use the values from them to affect the world, and return inputs from the world as sources to the main function.
It's a... guess what?
Cycle!
Demo
A basic counter example, with increment and decrement buttons, and a number.
That's it!
Explore more about Cycle.js at cycle.js.org
Cycle.js Intro
By Eshan Singh
Cycle.js Intro
- 94