Currying in JavaScript

Whilst being an object-oriented language, JavaScript still takes a lot of ideas from functional languages. One which it dosen’t implement though, is the idea of currying.
What’s currying then? You might ask, well, here’s the definition according to wikipedia:

In mathematics and computer science, currying, invented by Moses Schönfinkel and later re-invented by Haskell Curry,[1] is the technique of transforming a function that takes multiple arguments (or more accurately an n-tuple as its argument) in such a way that it can be called as a chain of functions each with a single argument.

So basically, it let’s you fill in some arguments to a function before hand and return a new function which you will subsequently call instead, or default arguments on steroids if you will.
Here’s a few examples of what we could do if JavaScript was capable of currying:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Array to csc
Array.prototype.arrayToCsv = Array.prototype.join.curry("; ");

["Patrik", "Hedman", "Stockholm"].arrayToCsv(); //=> "Patrik; Hedman; Stockholm"


// And back
String.prototype.csvToArray = String.prototype.split.curry(/;\s*/);

("Patrik; Hedman; Stockholm").csvToArray(); //=> ["Patrik", "Hedman", "Stockholm"]


// The undefined parameter will be replaced with the
// callback function passed to clicker();
var clicker = document.body.addEventListener.curry("click", undefined, false);
clicker(function(){
    console.log( "Curryfied click event." );
});

Pretty sweet, but it wont work since there is no curry() function in JavaScript, not a problem, implementing one is pretty straightforward:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Function.prototype.curry = function() {
    // Save references to this and the arguments so we can
    // acces them from the closure
    var fn   = this,
        args = Array.prototype.slice.call( arguments );
                   
    return function() {
        var arg = 0;
        for ( var i = 0; i < args.length && arg < arguments.length; i++ )
            if ( args[i] === undefined )
                // If the original argument is undefined
                // then replace it with the new one
                args[i] = arguments[arg++];

        // Call the original function with the current this as
        // the context and the newly constructed argument list
        return fn.apply(this, args);
    };
};
Posted in JavaScript, Programming at November 8th, 2009. Trackback URI: trackback Tags: , , Written by: Patrik Hedman

No Responses to “Currying in JavaScript”

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

pastbedti.me is using WP-Gravatar