Skip to the solution
HardDSA8 min read

How would you implement a curry() function that supports partial application with placeholder arguments?

255 views

The problem

Question presented to candidate: "Implement a curry function that turns any function into one that can be called with its arguments spread across multiple calls β€” curry(add)(1)(2)(3) should equal add(1, 2, 3). Now extend it to support placeholders, so a caller can skip an argument in an early call and supply it in a later one β€” curry(add)(_, 2, 3)(1) should also equal add(1, 2, 3). How do you decide, at each call, whether there are finally enough real arguments to actually invoke the original function?"

What a strong answer should cover:

  • The curried function needs to know the target function's arity (how many arguments it expects) β€” usually fn.length, though that is wrong for variadic (rest-parameter) functions, so a real implementation should accept an explicit arity override.
  • At each call, the function is only actually invoked once there are at least arity arguments collected AND none of the first arity slots is still a placeholder β€” both conditions matter, not just the count.
  • A placeholder is typically a unique sentinel value (a Symbol, or a well-known exported constant like curry.placeholder, sometimes aliased to _) β€” never a plain string like "_", since that could collide with a genuine argument value.
  • When a follow-up call arrives, its new arguments should fill EXISTING placeholders first, left to right, and only append as new trailing arguments once every existing placeholder has been filled.
  • Multiple placeholders in the same call must each be individually fillable, potentially across multiple separate follow-up calls, not just in one single all-at-once fill.
  • A correct implementation is a straightforward extension of classic curry: the recursive/closure-returning structure stays the same, only the "are we done yet" check and the "how do we merge args" logic change to account for placeholders.

Clarifying questions expected:

  • "Should the placeholder be exported as part of the curry function itself, like curry.placeholder, or does the caller supply their own sentinel value?" β€” affects the public API shape.
  • "What happens if a follow-up call supplies MORE real values than there are placeholders left to fill?" β€” a genuine edge case worth resolving explicitly (the extra values are typically appended after the merged, placeholder-filled arguments).

Code / implementation expected: Yes β€” a full, runnable curry implementation with placeholder support, plus a real, multi-case test suite proving correct behavior for single, multiple, and progressively-filled placeholders.

  • functional
  • tricky
  • real-world

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

8 min read Β· 7 sections

Run the code

Edit the code and run it here. Each console line with an expected value becomes a test.

JavaScriptcurry() with placeholder support, plus a real 14-case test suite (run directly)

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 158 of 165 in JavaScript

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextHard

How does V8 Array copy-on-write optimization work for `toSorted`/`toReversed`/`toSpliced`/`with`?

Continue