I believe that you could simply use Function.prototype.bind
. That gives you all the flexibility you need, wheter you want the result of the function right away or simply push another value into the arguments until you decide to execute.
function sum() {
return [].reduce.call(arguments, function (c, n) {
return c + n;
});
}
sum(1, 2); //3
var sum2 = sum.bind(null, 1, 2);
sum2(); //3
var sum3 = sum2.bind(null, 3);
sum3(); //6
You could also use a helper function like:
function curry(fn) {
var c = curry.bind(this, fn = fn.bind.apply(fn, [this].concat([].slice.call(arguments, 1))));
c.exec = fn;
return c;
}
curry(sum, 1, 2)(3)(4, 5)(6, 7, 8).exec(); //36
Also this is very flexible as you do not have to chain, you can re-use the same curried function.
var sumOnePlus = curry(sum, 1);
sumOnePlus.exec(2); //3;
sumOnePlus.exec(3); //4;