Functional Patterns

Currying turns f(a, b, c) into f(a)(b)(c) so arguments can be pre-filled. Composition chains one-argument functions: pipe(f, g)(x) is g(f(x)). Memoization caches the results of a pure function in a closure. Recursion calls itself on smaller parts, a natural fit for trees such as the DOM or JSON.

curry, pipe and a memoized recursive Fibonacci written from scratchJavaScriptLive
const curry = (fn) => function curried(...args) {
  return args.length >= fn.length ? fn(...args) : (...more) => curried(...args, ...more);
};
const pipe = (...fns) => (x) => fns.reduce((acc, f) => f(acc), x);
const memoize = (fn, cache = new Map()) => (n) => {
  if (!cache.has(n)) cache.set(n, fn(n));
  return cache.get(n);
};
const add = curry((a, b, c) => a + b + c);
const slugify = pipe((s) => s.trim(), (s) => s.toLowerCase(), (s) => s.replaceAll(" ", "-"));
let calls = 0;
const fib = memoize((n) => (calls++, n < 2 ? n : fib(n - 1) + fib(n - 2)));  // recursive
console.log(add(1)(2)(3), add(1, 2)(3), slugify("  Hello Curry World "), fib(50), calls);

Memoized, fib(50) runs its body 51 times instead of over 40 billion. The call stack limits recursion depth (Node.js 2,131 throws a RangeError after about 12,000 frames), and only Safari 10 implements ES2015 proper tail calls, so turn deep recursion into a loop. Libraries: Lodash 61,278 (https://github.com/lodash/lodash 61,278 ) offers _.curry, _.memoize and _.flow, and Ramda 24,047 (https://github.com/ramda/ramda 24,047 ) auto-curries every function; both are MIT-licensed npm 2,036 packages.