Spread and Gather: Array In, Arguments Out
The adapter for when a function wants individual arguments but you only have an array, and its exact inverse.
Flip and reverseArgs fix the order of arguments. This last shape mismatch is about something else entirely: whether the values arrive as an array, or as separate arguments.
The Problem: A Function Wants Arguments, You Have an Array
function total(a, b, c) {
return a + b + c;
}
const values = [10, 20, 30];
total(values); // "10,20,30" + undefined + undefined, not what you wanttotal expects three separate numbers. All you have is one array. Calling it directly hands the whole array to a, and leaves b and c empty.
The Adapter: Spread
function spreadArgs(fn) {
return function (argsArray) {
return fn(...argsArray);
};
}
const totalFromArray = spreadArgs(total);
totalFromArray([10, 20, 30]); // 60spreadArgs takes a function expecting individual arguments and returns a new one that instead expects a single array, spreading it out with ... before calling the original. This exact adapter is usually just called apply in most functional libraries, the same name as JavaScript's own long-standing Function.prototype.apply.
You might not reach for the wrapped version every time, total(...values) inline does the same thing on the spot. The wrapped form earns its keep when you need to hand the adapted function to something else as a callback:
[[10, 20, 30], [1, 2, 3]].map(spreadArgs(total));
// [60, 6]Inline spread syntax can't do that. You need an actual function to pass to .map(), and spreadArgs(total) is exactly that.
The Inverse: Gather
Flip the problem around: a function is built to take one array, but you've got individual values instead.
function gatherArgs(fn) {
return function (...args) {
return fn(args);
};
}
function total3([a, b, c]) {
return a + b + c;
}
const totalFromValues = gatherArgs(total3);
totalFromValues(10, 20, 30); // 60The only difference from spreadArgs is which side the ... sits on. Spread takes the array apart on the way in. Gather collects loose arguments back into one array before the underlying function ever sees them. Most libraries call this one unapply, the mirror image of apply.
The Pattern Behind All of This
Four adapters now, unary, binary, flip, spreadArgs/gatherArgs, and every one of them is the same move: take a function, hand back a new function with a different shape, change nothing about what it actually computes.
That's genuinely the whole trick behind higher-order functions reshaping arguments. Once you've built a couple of these yourself, recognizing the pattern in any functional library's source code stops being intimidating, it's the same handful of ideas wearing different names.
Keep reading