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.

September 9, 20262 min read13 / 27

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

JavaScript
function total(a, b, c) { return a + b + c; } const values = [10, 20, 30]; total(values); // "10,20,30" + undefined + undefined, not what you want

total 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

JavaScript
function spreadArgs(fn) { return function (argsArray) { return fn(...argsArray); }; } const totalFromArray = spreadArgs(total); totalFromArray([10, 20, 30]); // 60

spreadArgs 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.

[10, 20, 30]input
spreadArgs(total)the adapter
60output

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:

JavaScript
[[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.

JavaScript
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); // 60

The 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.