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
arityarguments collected AND none of the firstarityslots 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 likecurry.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.