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
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
// 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
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.
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
composeandpipeutilities. - 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 | uniqcomposes four programs where each output feeds the next input.