Master

Advanced Functional Patterns

Compose behavior with currying, composition, and immutability.

What you will see

1 10

About 2 min of reading

Try It

Compose pipelines of small functions, curry multi-argument functions into chains, and update state immutably. Each transformation produces a fresh value rather than mutating the old.

1

Curry a three-argument function into a chain of single-argument functions. Supply arguments one call at a time until the final call returns the result.

const multiply = a => b => c => a * b * c; const triple = multiply(3); const six = triple(2); console.log(six(1));

Before you run it, say out loud what it will print. Then open the answer.

What it prints
6
Currying turns a multi-argument function into a chain of single-argument functions. Each call returns a new function until all arguments are supplied.
2

Compose two functions that apply right-to-left: add one, then double. Feed in three and read the result to see the pipeline in order.

const compose = (...fns) => (x) => fns.reduceRight((acc, fn) => fn(acc), x); const add1 = x => x + 1; const double = x => x * 2; const add1ThenDouble = compose(double, add1); console.log(add1ThenDouble(3));

Before you run it, say out loud what it will print. Then open the answer.

What it prints
8
`compose` applies functions right-to-left; `pipe` applies left-to-right. Composition builds complex behavior from small, testable pieces.
3

Update an object by spreading a patch over a copy, leaving the original untouched. Print both values to confirm the source stayed the same.

const update = (state, patch) => ({ ...state, ...patch }); const s = { x: 1, y: 2 }; const s2 = update(s, { x: 10 }); console.log(s.x, s2.x);

Before you run it, say out loud what it will print. Then open the answer.

What it prints
1 10
Immutable updates create new state instead of mutating the old. This is the basis of predictable state in frameworks like Redux and React.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

Functions compose into pipelines; currying partially applies arguments; immutable updates produce new state.
1 Apply an argument -> return a function
↓
2 Compose functions -> chain transformations
↓
3 Run over data -> new immutable result
↓
4 Next stage reads the new state
Why this works
Purity and side effects

A pure function depends only on its inputs and produces no side effects:

// pure
const pure = (a, b) => a + b;
// impure
let cache = [];
const impure = (a) => { cache.push(a); return a; };

Pure functions are deterministic and easy to test. Real programs need side effects (I/O, state), so isolate them at the edges and keep the core pure. This makes reasoning and testing tractable.

Effectives and monads

Patterns like Maybe/Either handle missing values without null checks:

const maybe = (fn) => x => x == null ? null : fn(x);
const safeDiv = maybe(b => a => a / b);
console.log(safeDiv(0)(5));   // null (avoid division by zero)

While full monadic style is advanced, the idea of wrapping values that may fail (Option/Either) and composing over them is a powerful way to keep null handling out of your core logic.

Examples

Currying

One argument at a time

const multiply = a => b => c => a * b * c;
const triple = multiply(3);   // b => c => 3 * b * c
const six = triple(2);        // c => 6 * c
console.log(six(1));          // 6

Currying transforms a multi-argument function into a chain of single-argument functions. Each call returns a new function until all arguments are supplied.

Function composition

Chaining transformations

const compose = (...fns) => (x) =>
  fns.reduceRight((acc, fn) => fn(acc), x);

const add1 = x => x + 1;
const double = x => x * 2;
const add1ThenDouble = compose(double, add1);
console.log(add1ThenDouble(3));   // 8 (3+1=4, 4*2=8)

compose applies functions right-to-left. pipe is the same but left-to-right. Composition builds complex behavior from small, testable pieces.

Immutability helpers

Pure state updates

const update = (state, patch) => ({ ...state, ...patch });
const move = (arr, i, val) =>
  [...arr.slice(0, i), val, ...arr.slice(i + 1)];

const s = { x: 1, y: 2 };
const s2 = update(s, { x: 10 });
console.log(s.x, s2.x);   // 1 10 (s unchanged)

Immutable updates create new state instead of mutating the old. This is the basis of predictable state in frameworks like Redux and React.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Decorators and Metaprogramming
Previous Lesson
Decorators and Metaprogramming