https://slides.com/artfuldev/frp-with-cycle-js/live/
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
Where does this get data from?
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
Where does this get data from?
Does this get modified?
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
Where does this get data from?
Does this get modified?
How does this happen?
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
What if getTodos() gets called again?
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
What if getTodos() gets called again?
while the save is still executing?
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
const todos = getTodos();
const updatedTodos = addNewTodo(todos, newTodo);
saveTodos(updatedTodos);
A way to write programs in terms of simple functions
Given an array of numbers, multiply each number by a constant and print the result.
var numbers = [3, 1, 7];
var constant = 2;
// 6 2 14
Given an array of numbers, multiply each number by a constant and print the result.
var numbers = [3, 1, 7];
var constant = 2;
// Imperative / Prodedural
for(var i = 0; i < numbers.length; i++) {
console.log(numbers[i] * constant);
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
// Imperative / Prodedural
for(var i = 0; i < numbers.length; i++) {
console.log(numbers[i] * constant);
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
// Imperative / Prodedural
for(var i = 0; i < numbers.length; i++) {
console.log(numbers[i] * constant);
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
// Imperative / Prodedural
for(var i = 0; i < numbers.length; i++) {
console.log(numbers[i] * constant);
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
// Imperative / Prodedural
for(var i = 0; i < numbers.length; i++) {
console.log(numbers[i] * constant);
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
// 6 2 14
multiplies 2 numbers
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
// 6 2 14
multiplies 2 numbers
prints 1 argument
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
// result(x) is the same as product(constant, x)
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
// result(x) is the same as product(constant, x)
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
// result(x) is the same as product(constant, x)
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
// result(x) is the same as product(constant, x)
function printResult(x) {
print(result(x));
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
// result(x) is the same as product(constant, x)
function printResult(x) {
print(result(x));
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
function printResult(x) {
print(result(x));
}
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
function printResult(x) {
print(result(x));
}
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
simple, small, reusable functions
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
function printResult(x) {
print(result(x));
}
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
simple, small, reusable functions
application logic functions
var numbers = [3, 1, 7];
var constant = 2;
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
const result = product.bind(null, constant);
function printResult(x) {
print(result(x));
}
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
simple, small, reusable functions
application logic functions
iteration
var numbers = [3, 1, 7];
var constant = 2;
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
numbers.forEach(printResult);
var numbers = [3, 1, 7];
var constant = 2;
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
numbers.forEach(printResult);
same result
var numbers = [3, 1, 7];
var constant = 2;
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
numbers.forEach(printResult);
same result
numbers // [3, 1, 7]
.map(result) // [6, 2, 14]
.forEach(print); // 6 2 14
var numbers = [3, 1, 7];
var constant = 2;
for(var i = 0; i < numbers.length; i++) {
printResult(numbers[i]);
}
// 6 2 14
numbers.forEach(printResult);
same result
numbers // [3, 1, 7]
.map(result) // [6, 2, 14]
.forEach(print); // 6 2 14
clearer semantics
function product(a, b) {
return a * b;
}
function product(a, b) {
return a * b;
}
function product(a, b) {
return a * b;
}
function print(x) {
console.log(x);
}
function print(x) {
console.log(x);
}
not pure
console is defined outside
function print(x) {
console.log(x);
}
not pure
has side effects on the terminal
function getTime() {
return new Date();
}
function getTime() {
return new Date();
}
not pure
does not operate on inputs?
function getTime() {
return new Date();
}
not pure
does not operate on inputs? not really
function getTime() {
return new Date();
}
not pure
does not return same outputs every time
function product(a, b) {
return a * b;
}
A way to write programs in terms of simple functions
A way to write programs in terms of simple functions
var a = 3;
var b = 5;
var c = a + b;
// c is 8
var a = 3;
var b = 5;
var c = a + b;
// c is 8
a = -3;
// c is still 8
var a = 3;
var b = 5;
var c = a + b;
// c is 8
a = -3;
// c is still 8
var c = a + b;
var c = a + b;
???
var a = 3;
var b = 5;
var c = a + b;
// c is 8
a = -3;
// c is still 8
var a = 3;
var b = 5;
var c = a + b;
// c is 8
a = -3;
// c is still 8
c = a + b;
// c is now 3
var a = 3;
var b = 5;
var c = a + b;
// c is 8
a = -3;
// c is still 8
c = a + b;
// c is now 3
const numbers = [1, 2, 3];
numbers.forEach(print);
// 1 2 3
const numbers = [1, 2, 3];
numbers.forEach(print);
// 1 2 3
numbers.push(100);
// nothing happens
// stream that never emits
// -------------------
// stream that never ends
// ----1---2-3----4-5-
// stream that terminates with error
// ----1---2---3----X
// stream that terminates with complete
// --1---2-3--4-|
// stream that never emits
// -------------------
// stream that never ends
// ----1---2-3----4-5-
// stream that terminates with error
// ----1---2---3----X
// stream that terminates with complete
// --1---2-3--4-|
A way to write programs in terms of simple functions
A way to code with data flows and propagation of change
A way to write programs in terms of simple functions
A way to code with data flows and propagation of change
Problem: Create a simple application that has a counter with increment and decrement buttons
Problem: Create a simple application that has a counter with increment and decrement buttons
import xs from 'xstream';
import { run } from '@cycle/xstream-run';
import { div, button, p, makeDOMDriver } from '@cycle/dom';
function main(sources) {
const intent$ = xs.merge<number>(
sources.DOM.select('.decrement').events('click').map(ev => -1),
sources.DOM.select('.increment').events('click').map(ev => 1)
);
const count$ = intent$.fold((count, intent) => count + intent, 0);
return {
DOM: count$.map(count =>
div([
button('.decrement', 'Decrement'),
button('.increment', 'Increment'),
p('Counter: ' + count)
])
)
};
}
run(main, {
DOM: makeDOMDriver('#app')
});
A way to write programs in terms of simple functions
A way to code with data flows and propagation of change
A functional and reactive framework for cleaner code
A way to write programs in terms of simple functions
A way to code with data flows and propagation of change
A functional and reactive framework for cleaner code
Uses functional reactive streams to describe the data flow in application
Side effects (DOM, HTTP, etc) are isolated via drivers
Works out of the box with real time backends (WebSockets, IoT)
slides artfuldev/frp-with-cycle-js/
twitter @theartfuldev
github @artfuldev