It’s based on pure functions. Pure functions return same output from same input data and don’t modify anything outside itself (no side effects).

Currying

const multiply = (a, b, c) => a*b*c;
const multiplyBy5 = multiply.bind(null, 5);
console.log(multiplyBy5(4, 10));

Caching and Memorization

It can be done with closures:

function addTo80Factory() {
  let cache = {};
  return function (n) {
    if (n in cache) {
      return cache[n];
    } else {
      console.log('long time');
      const result = n + 80;
      cache[n] = result;
      return result;
    }
  };
}

const addTo80 = addTo80Factory();

console.log(addTo80(5));
console.log(addTo80(5));
console.log(addTo80(10));

Compose and Pipe

Main principle of composition:

const compose = (f, g) => (data) => f(g(data));
console.log(compose((x) => x*3, Math.abs)(-20));

Pipe is the opposite:

fn1(fn2(fn3(data)));
compose(fn1, fn2, fn3)(data);
pipe(fn3, fn2, fn1)(data);

Check the example of library: Ramda.js

Functions

Concat arrays

const newArray = [].concat(array);