yaodebian @ yaodebian.me

Coding Practice: Implement Currying With Placeholder Support

Sep 29, 2025

Question

please implement curry() which also supports placeholder.

Here is an example

function join(a, b, c) {
  return `${a}_${b}_${c}`
}
const curriedJoin = curry(join)
const _ = curry.placeholder
curriedJoin(1, 2, 3) // '1_2_3'
curriedJoin(_, 2)(1, 3) // '1_2_3'
curriedJoin(_, _, _)(1)(_, 3)(2) // '1_2_3'

Solution

Let’s compare with following arguments:

  • (_, _, _) with (1) , we can get (1, _, _)
  • (1, _, ) with (, 3) , we can get (1, _, 3)
  • (1, _, 3) with (2) , we can get (1, 2, 3)

We can find a pattern: if this call including placeholder argument, the next call’s arguments will fill the placeholder of the last call’s rest placeholder arguments.

Now, we have understand the question, so we can implement it.

function curry(fn) {
  const context = this
  return function curried(...args) {
    const isComplete = args.length >= fn.length && !args.slice(0, fn.length).includes(curry.placeholder)
    if (isComplete) {
      return fn.apply(context, args)
    }
    return function (...nextArgs) {
      const argList = args.map((arg) => {
        return arg === curry.placeholder && nextArgs.length ? nextArgs.shift() : arg
      })
      return curried.apply(context, argList.concat(nextArgs))
    }
  }
}
> comment on mastodon / twitter
>
CC BY-NC-SA 4.0 2021-PRESENT © Anthony Fu