18.8.07

Currying in JavaScript

We can make our functions curried in JavaScript:
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.