Labs ICT
Pro Login

Composition

Function Composition

Function composition is combining two or more functions to create a new function. The output of one function becomes the input of the next. This lets you build complex operations from simple, reusable pieces.

const double = x => x * 2;
const addOne = x => x + 1;

// Compose: first double, then addOne
const doubleThenAddOne = x => addOne(double(x));

console.log(doubleThenAddOne(3)); // 7 (3*2 + 1)

Generic Compose Function

You can write a compose utility that combines any number of functions. It processes them from right to left, like mathematical function composition.

function compose(...fns) {
  return function(x) {
    return fns.reduceRight((acc, fn) => fn(acc), x);
  };
}

const process = compose(
  x => x.toUpperCase(),
  x => x.trim(),
  x => `Hello, ${x}!`
);

console.log(process("  world  ")); // "HELLO, WORLD!"

Pipe vs Compose

pipe is like compose but reads left to right. Many developers find pipe more readable because it follows the natural order of execution.

function pipe(...fns) {
  return function(x) {
    return fns.reduce((acc, fn) => fn(acc), x);
  };
}

const process = pipe(
  x => x.trim(),
  x => x.toUpperCase(),
  x => `Hello, ${x}!`
);

console.log(process("  world  ")); // "HELLO, WORLD!"
Try it Yourself →

Real-World Composition

Composition is great for data processing pipelines, formatters, and middleware systems.

const formatPrice = price =>
  `$${price.toFixed(2)}`;

const applyDiscount = (discount) => (price) =>
  price * (1 - discount);

const addTax = (taxRate) => (price) =>
  price * (1 + taxRate);

const calculateFinalPrice = pipe(
  applyDiscount(0.1),
  addTax(0.08),
  formatPrice
);

console.log(calculateFinalPrice(100)); // "$97.20"

Summary

Composition builds complex functions from simple ones. Use compose (right-to-left) or pipe (left-to-right) to create clean, reusable data processing pipelines.