When I read about curry function, I think it's hard to create a recursion for building nested function. Then I take a look at ramda's implementation, it's true that to create an curried function with arbitrary number of arguments. Then, why not building it with string like this:
function curry(fn, arity) {
arity = typeof arity === 'undefined' ? fn.length : arity
if (arity < 1) {
return fn
}
function build(n, space = 2, args = []) {
if (n < 1) {
args = args.map(arg => 'a' + arg)
return `fn(${args.join(', ')})`
} else {
return `function (a${n}) {\n${' '.repeat(space)}` +
`return ${build(n - 1, space + 2, args.concat(n))}\n` +
`${' '.repeat(space - 2)}}`
}
}
const curryCreator = new Function('fn', 'return ' + build(arity))
return curryCreator(fn)
}
It can be used like this:
function sum5(a, b, c, d, e) {
return a + b + c + d + e
}
const sum = curry(sum5)
Which will produce this:
function (a5) {
return function (a4) {
return function (a3) {
return function (a2) {
return function (a1) {
return fn(a5, a4, a3, a2, a1)
}
}
}
}
}
How bad it can be to use new Function
for this functionality?
The use case is just to generate a function and argument placeholder like
in the example above. My question is more specific than this which
addresses the generic use case of eval
or new Function
. As you can see
in my example, it's a private function which is won't be called in another
place.