precalculus25 min

Function Composition

Combining functions by feeding the output of one into the input of another

0/9Not Started

Why This Matters

In programming, you chain operations constantly: format the result of a calculation, filter the output of a query, transform the result of a fetch. In mathematics, this same idea is called function composition. If f(x) = 2x and g(x) = x + 3, then f(g(x)) means "first apply g, then apply f to the result." You are feeding the output of the inner function into the outer function.

Function composition is the mathematical foundation for pipelines, middleware chains, and functional programming patterns like map, filter, and reduce chained together. Understanding the order of operations -- which function runs first and which runs second -- prevents subtle bugs and deepens your grasp of how data flows through transformations.

Define Terms

Visual Model

Input xStarting value
g(x)Inner function applied first
g(x) resultIntermediate value
f(...)Outer function applied second
f(g(x))Final composed result
(f . g)(x)Composition operator

The full process at a glance. Click Start tour to walk through each step.

Function composition feeds the output of the inner function into the input of the outer function.

Code Example

Code
// Define two simple functions
function f(x) { return 2 * x; }
function g(x) { return x + 3; }

// Compose f(g(x)): apply g first, then f
console.log("f(g(4)):", f(g(4)));   // g(4)=7, f(7)=14
console.log("g(f(4)):", g(f(4)));   // f(4)=8, g(8)=11

// Generic compose function
function compose(outer, inner) {
  return function(x) {
    return outer(inner(x));
  };
}

const fg = compose(f, g);
console.log("composed(4):", fg(4));  // 14
console.log("composed(0):", fg(0));  // 6

// Compose from data: given arrays of [x,y] pairs
function composePairs(fPairs, gPairs) {
  const gMap = new Map(gPairs);
  const fMap = new Map(fPairs);
  const result = [];
  for (const [x] of gPairs) {
    const gx = gMap.get(x);
    if (gx !== undefined && fMap.has(gx)) {
      result.push([x, fMap.get(gx)]);
    }
  }
  return result;
}

const fData = [[1,2],[2,4],[3,6],[7,14]];
const gData = [[1,3],[2,1],[3,7],[4,2]];
console.log("composed pairs:", JSON.stringify(composePairs(fData, gData)));
// [[1,6],[2,2],[3,14],[4,4]]

Interactive Experiment

Try these exercises:

  • Compute f(g(x)) and g(f(x)) for f(x) = x^2 and g(x) = x - 1 with x = 3. Are they the same?
  • Create a compose function that chains three functions: h(g(f(x))).
  • What happens if the inner function returns a value outside the domain of the outer function?
  • Try composing a function with its inverse (like f(x) = 2x and g(x) = x/2). What do you get?
  • Build a pipeline that converts Celsius to Fahrenheit by composing multiply-by-9/5 with add-32.

Quick Quiz

Coding Challenge

Compose Functions from Data Pairs

Write a function called `composePairs` that takes two arrays of [x, y] pairs representing functions f and g, and returns a new array of [x, f(g(x))] pairs. For each x in gPairs, look up g(x), then look up f(g(x)). If either lookup is not found, skip that x. Return the result sorted by x.

Loading editor...

Real-World Usage

Function composition appears everywhere in software:

  • Middleware chains: In Express.js or Django, each middleware function processes and passes data to the next, forming a composition pipeline.
  • Data pipelines: ETL (Extract, Transform, Load) processes compose transformations: parse JSON, filter rows, normalize values, write to database.
  • Functional programming: Languages like Haskell have a built-in composition operator (.). In JavaScript, libraries like Ramda and lodash/fp provide compose and pipe utilities.
  • React higher-order components: Wrapping components with HOCs like withAuth(withTheme(MyComponent)) is function composition applied to UI.
  • Unix pipes: cat file | grep pattern | sort | uniq composes four programs where each output feeds the next input.

Connections