The Shape of a Function
The real difference between a parameter and an argument, and why functional programmers obsess over how many inputs and outputs a function has.
The last few posts settled what a function is allowed to touch. Now this series shifts to a more practical question: what a function actually receives.
Two words get used interchangeably that actually mean different things: parameter and argument.
function getTotal(price, tax) {
return price + tax;
}
getTotal(40, 4);price and tax are parameters, the names written into the function's definition. 40 and 4 are arguments, the actual values handed over at the call site. Arguments get assigned to parameters when the function runs.
What "Shape" Means
Beyond naming, there's a more useful question: how many inputs does a function take, and how many outputs does it give back? That combination is worth naming too. This series calls it a function's shape: not a strict type signature, just an informal way to talk about what goes in and what comes out.
Three shapes come up constantly:
(x) → y(x, y) → z(a, b, c...) → zdiscountedPrice(price) takes one input, it's unary. getTotal(price, tax) takes two, it's binary. A function like logOrder(id, item, qty, total), four separate inputs, is n-ary, the catch-all name for anything with three or more.
Why the Shape Actually Matters
Picture function calls like pipe fittings. A pipe that outputs a 2-inch stream doesn't connect to one that expects a 4-inch input without something in between to adapt it.
Functions are the same, especially once you start chaining them together. If one function hands back a value, and the next one in line expects a different shape of input, they don't fit together, no matter how correct each one is on its own.
That's why functional programmers care about shape as much as they do. A codebase full of functions with incompatible shapes means constant one-off glue code holding everything together. A codebase where shapes are kept small and predictable is one where functions snap into each other with far less friction.
Smaller Shapes Are Preferred, and Rare Is Suspicious
Given the choice, functional code leans heavily toward unary functions, then binary. A function that needs three, four, or more separate inputs is harder to plug into anything else, since there are more ways for its shape to mismatch whatever's calling it.
That doesn't make n-ary functions wrong. It's a signal worth noticing: the more inputs a function needs, the more you're committing to exactly how it'll be called, and the less flexible it becomes everywhere else.
None of this means reshaping a function's actual parameters every time you need a different shape. The next posts in this series cover a set of small, reusable tools for adapting a function's shape from the outside, without touching its definition at all.
Keep reading