function curry(f, needed_len) { if (needed_len == undefined) needed_len = f.length; var curried = function() { var curried_args = arguments; if (curried_args.length >= needed_len) { return f.apply(this, arguments); } else { var curry_result_function = function() { var args = []; for(var i=0; i<curried_args.length; i++) args[args.length] = curried_args[i]; for(var i=0; i<arguments.length; i++) args[args.length] = arguments[i]; return f.apply(this, args); }; return curry(curry_result_function, needed_len-curried_args.length); } }; return curried; }And usage:
var curried_add = curry(function (a, b, c) { return a + b + c; }); print(curried_add(1)(2)(3)); print(curried_add(1)()(2)()(3)); print(curried_add(1,2,3)); print(curried_add(1)(2,3)); print(curried_add(1,2)(3));See also next pages for other implementations: http://www.dustindiaz.com/javascript-curry http://www.svendtofte.com/code/curried_javascript/
Note: after some more googling about currying in JavaScript, it's very interesting to see that http://www.coryhudson.com/blog/2007/03/10/javascript-currying-redux/ contains an almost identical implementation.