I'm unsure about this part:
if(!args1.length) {
return sum(args1);
}
If the array's empty, you could just return zero - no need to call sum
.
Secondly, you're doubling possible return types for add
. You either get a new curried function, or you get a number.
This goes for the curried function as well, really, as it too will return either a sum or another function.
So either way, it's kinda tricky. Partial application/currying is kinda difficult if you have something like this, that you can "keep currying" forever.
Anyway, sticking to your current structure, it can be simplified somewhat. Notably, you don't have to create a new closure for each invocation. And you can get rid of the double !argsN.length
checks and calls to sum
:
function add(...initial) {
let list = [];
function adder(...values) {
if(!values.length) {
return list.reduce((sum, n) => sum + n, 0);
}
list.push(...values);
return adder;
}
return adder(...initial);
}
Here, I've named the nested function, so it can return itself. After the initial call to add
, the nested adder
function is created, closes over the list
array, and is invoked. It then either returns the sum or it returns itself. I.e. only one closure is created, and subsequent calls simply update the closed over list
- or sums it.
adder
also handles all the input checking etc.. The outer add
function only exists to create and invoke it.
Also note that I renamed the argument arrays, as args1
and args2
really aren't too descriptive. And that the ...
-splat works for both definition and invocation. And, lastly, since it only need to do a sum in 1 place, there's no need for a separate sum
function.