Useful Cheatsheetsusefulcheatsheets.com
JavaScript Currying and Composition
Chapter 28 · Page 221
Advanced

JavaScript Currying and Composition

Transform multi-argument functions into chained calls and combine small functions into pipelines.

TL;DR

  1. 01Transform multi-argument functions into nested single-argument curry functions.
  2. 02Apply subset arguments up front to generate specialized function presets.
  3. 03Compose independent single-input operations into clean linear data pipelines.

Tips

  1. 01Design small, single-purpose functions to make currying and function composition patterns easier to build.
  2. 02Prefer the pipe helper to construct left-to-right processing streams matching natural reading orders.

Warnings

  1. 01Avoid currying every simple method because unnecessary function wrappers hurt overall script readability.
  2. 02Validate data parameters at each pipeline step to prevent silent runtime type errors.
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Currying and Composition
Chapter 28 · Page 222
Advanced

JavaScript Currying and Composition

(continued)

What Currying Does

  • Currying chains

    Converts multi-argument functions into sequential single-argument calls.

    function add(a, b, c) {
      return a + b + c;
    }
    const curryAdd = a => b => c => a + b + c;
    curryAdd(1)(2)(3); // 6
  • Call execution

    Invokes the original function only after all arguments are received.

    const add5 = curryAdd(5);
    add5(2)(3); // 10
  • Arrow notation

    Uses nested arrow functions to construct inline curried definitions.

    const multiply = a => b => a * b;
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Currying and Composition
Chapter 28 · Page 223
Advanced

JavaScript Currying and Composition

(continued)

A Generic Curry Helper

  • curry() implementation

    Gathers arguments recursively until the count matches function arity.

    function curry(fn) {
      return function curried(...args) {
        if (args.length >= fn.length) {
          return fn.apply(this, args);
        }
        return (...next) => {
          return curried.apply(this, [...args, ...next]);
        };
      };
    }
  • Function length

    Resolves function arity dynamically using the fn.length property.

    const sum = curry((a, b, c) => a + b + c);
    sum(1)(2)(3); // 6
    sum(1, 2)(3); // 6
  • Arity configurations

    Specifies manual arity limits for functions with default parameters.

    function curryN(fn, arity) {
      return function collect(...args) {
        return args.length >= arity
          ? fn(...args)
          : (...more) => collect(...args, ...more);
      };
    }
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Currying and Composition
Chapter 28 · Page 224
Advanced

JavaScript Currying and Composition

(continued)

Partial Application

  • bind() method

    Binds arguments up front using the built-in prototype bind method.

    function mult(a, b) { return a * b; }
    const double = mult.bind(null, 2);
    double(5); // 10
  • Custom partial

    Builds a partial helper to bind arguments without bind context.

    function partial(fn, ...fixed) {
      return (...rest) => fn(...fixed, ...rest);
    }
    const greet = partial((g, n) => g + n, "Hi ");
    greet("Ada"); // "Hi Ada!"
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Currying and Composition
Chapter 28 · Page 225
Advanced

JavaScript Currying and Composition

(continued)

Composing Functions

  • compose() helper

    Combines functions executing right-to-left like mathematical equations.

    const compose = (...fns) => x =>
      fns.reduceRight((acc, f) => f(acc), x);
    const shout = s => s.toUpperCase() + "!";
    const format = compose(shout, s => s.trim());
    format("  hi  "); // "HI!"
  • pipe() helper

    Combines functions executing left-to-right to match reading order.

    const pipe = (...fns) => x =>
      fns.reduce((acc, f) => f(acc), x);
    const run = pipe(s => s.trim(), s => s.toUpperCase());
    run("  hi  "); // "HI"
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Currying and Composition
Chapter 28 · Page 226
Advanced

JavaScript Currying and Composition

(continued)

Practical Use Cases

  • Curried validation

    Pre-fills validation parameters to generate specialized rule checklists.

    const minLength = curry((min, s) => s.length >= min);
    const isValid = minLength(3);
    isValid("ok"); // false
  • Middleware execution

    Threads orders or values through sequential modifier function lists.

    const processOrder = pipe(
      applyDiscount,
      addTax
    );
    processOrder(100);
Notes
Useful Cheatsheetsusefulcheatsheets.com
JavaScript Currying and Composition
Chapter 28 · Page 227
Advanced

JavaScript Currying and Composition

(FAQ)

FAQ

Currying transforms a function to accept one argument per call sequentially. Partial application binds multiple arguments immediately and returns a function waiting for the remaining parameters.

Inspect target function arity using the length property. Recursively gather arguments until they match or exceed that length, then invoke the underlying function.

Both helpers chain functions together. Compose executes functions from right to left. Pipe executes them from left to right, matching sequential reading order.

Currying enables specialized helper construction by pre-filling configuration values. This reduces duplicate parameters and allows seamless integration inside pipeline composition chains.

Curried calls instantiate closure environments and nested calls. The performance cost is usually negligible. Avoid currying inside critical performance paths like tight execution loops.

Useful Cheatsheetsusefulcheatsheets.com
JavaScript Currying and Composition
Chapter 28 · Page 228
Advanced

JavaScript Currying and Composition

(In Practice)
In Practice

Order Processing Pipeline

Pairs a curried discount calculator with a left-to-right pipeline to process invoice figures.

  1. 01Write a generic currying helper to allow step-by-step argument input.
  2. 02Curry the discount calculation function and fix the percentage rate.
  3. 03Define standard tax and currency formatting math operations.
  4. 04Pipe the functions together to thread inputs through each step sequentially.
  5. 05Invoke the completed pipeline with a test order price.
const curry = fn => (...args) =>
  args.length >= fn.length
    ? fn(...args)
    : (...more) => curry(fn)(...args, ...more);

const applyDiscount = curry((rate, price) =>
  price * (1 - rate)
);
const applyTenPercentOff = applyDiscount(0.1);
const addTax = price => price * 1.08;
const format = price => "$" + price.toFixed(2);

const pipe = (...fns) => x =>
  fns.reduce((acc, fn) => fn(acc), x);

const processOrder = pipe(
  applyTenPercentOff,
  addTax,
  format
);

console.log(processOrder(100)); // "$97.20"
Takeaway

Pre-filling function parameters with currying yields simple unary steps that pipe links together smoothly.