AniUI Academy

Curry a variadic function

hardFunctions & Closures+350 XPPractice

Fixed-arity currying can watch fn.length to know when it has enough. A variadic function has fn.length of 0, so there is nothing to count towards, and the curried form needs an explicit end signal instead. The convention is a call with no arguments, which is also the trick behind the add(1)(2)(3) puzzle.

Implement variadicCurry(fn). It returns a collector function. Calling the collector with one or more arguments returns a new collector holding everything gathered so far, so arguments can be supplied one at a time or several at a time, over any number of calls. Calling a collector with no arguments invokes fn with all of the arguments gathered along that chain and returns its result — so variadicCurry(fn)() invokes fn with no arguments at all. Every collector is independent: branching off the same partially applied collector twice must give two separate results, with no arguments leaking between the branches.

Arguments

fnFunction
A variadic function. An empty call on the returned collector flushes everything into it.

Returns

Function — A collector that keeps returning a new collector until called with no arguments, which flushes.

Examples

const sum = variadicCurry((...nums) => nums.reduce((a, b) => a + b, 0));

sum(1)(2)(3)();     // 6
sum(1, 2)(3, 4)();  // 10
sum(1, 2, 3, 4)();  // 10
sum();              // 0 — immediate empty call still invokes fn
const sum = variadicCurry((...nums) => nums.reduce((a, b) => a + b, 0));
const startsWithThree = sum(1, 2);

startsWithThree(3)();  // 6
startsWithThree(10)(); // 13 — branches do not share arguments

Each call returns a fresh collector that closes over its own copy of the gathered arguments.

What it has to do

  • Collect arguments across any number of calls, one or several at a time.
  • Invoke fn with everything collected when a collector is called with no arguments.
  • Invoke fn with no arguments when the first call is empty.
  • Keep branches independent: reusing a partially applied collector must not accumulate arguments across uses.

Notes

  • collected.concat(args) produces a new array each time — reusing or mutating one array is what makes two branches start sharing arguments.
  • Unlike fixed-arity curry, there is no fn.length to count against. The empty call is the explicit signal that "I'm done, flush".

Stuck? The javascript course covers everything this challenge needs.

Try it yourself
Loading playground...
5 tests · +350 XP

Discussion

Sign in to post
Sign in to join the conversation.Sign in

No comments yet. Be the first to say something.