compose and pipe in js
Compose and Pipe in JavaScript
Functional pipeline architecture, unary composition, and point-free coding style.
The Manufacturing Factory Conveyor Belt
f(g(h(x))), evaluating from the inside out / right-to-left (`compose(stamp, paint, sand)`)."
Function composition combines multiple simple functions to build complex transformations. Output of each function becomes the input of the next, producing clean, declarative pipelines.
Mathematical Foundation
Given two functions f and g, composition is (f \circ g)(x) = f(g(x)). The innermost function evaluates first.
Unary Constraint
Functions in a pipeline must be unary (accept a single argument). Multi-argument functions should be curried first before entering the pipeline.
Implementing pipe() with reduce
`const pipe = (...fns) => (x) => fns.reduce((val, fn) => fn(val), x)`. Left-to-right execution flow.
Implementing compose() with reduceRight
`const compose = (...fns) => (x) => fns.reduceRight((val, fn) => fn(val), x)`. Right-to-left execution flow.
Building pipe and compose to format and sanitize user input data:
const trim = (str) => str.trim();
const toLowerCase = (str) => str.toLowerCase();
const wrapInTag = (tag) => (content) => `<${tag}>${content}</${tag}>`;
// Implementations
const pipe = (...fns) => (initialValue) =>
fns.reduce((acc, fn) => fn(acc), initialValue);
const compose = (...fns) => (initialValue) =>
fns.reduceRight((acc, fn) => fn(acc), initialValue);
// Clean text pipeline
const sanitizeUsername = pipe(
trim,
toLowerCase,
wrapInTag("span")
);
const mathCompose = compose(
(x) => x * 2, // 3. Multiplies 6 * 2 = 12
(x) => x + 1, // 2. Adds 5 + 1 = 6
(x) => Math.abs(x) // 1. Abs(-5) = 5
);
console.log(sanitizeUsername(" Alex_Dev "));
console.log("Math compose result:", mathCompose(-5));
<span>alex_dev</span>
Math compose result: 12
Passing Impure or Mutating Functions into Pipeline
The Risk: If a function inside a pipe mutates its input in-place instead of returning a new value, side effects pollute subsequent operations.
The Fix: Ensure every function in a compose/pipe pipeline is a pure function that returns a new value.
- ✓ `pipe()` evaluates Left-to-Right (natural reading order, uses `reduce`).
- ✓ `compose()` evaluates Right-to-Left (mathematical order, uses `reduceRight`).
- ✓ All pipeline functions must be unary (one argument in, one argument out).
- ✓ Use currying to adapt multi-argument functions into the pipeline.
- ✓ Enables clean "point-free" programming style.