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. No Comments
Tagged with , , . Written by: Patrik Hedman

So, a few days ago I finally decided to give JavaScript a proper chance and as it turns out; All those people who’s been blabbering on about how JavaScript actually is a very powerful language where right all along!

You see, just like Ruby, JavaScript is extremely flexible, for instance, here’s how you would typically loop over an array:

1
2
3
4
var myArray = [1, 2, 3, 4, 5];
for (var i=0; i < myArray.length; i++) {
    alert(myArray[i]);
};

However, in Ruby land we’ve grown to know and love the [].each { |elem| … } way of looping, JavaScript doesn’t have that but fortunately adding it yourself is trivial:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Extend the Array object with an each function
Array.prototype.each = function(fn) {
    // Loop through each element in this (which will be the
    // array instance we call each on)
    for (var i=0; i < this.length; i++) {
        // Call the callback function with it's context
        // set to the current array element
        fn.call(this[i]);
    };
};

// With our new each function in place we can now iterate
// over an array like this
[1, 2, 3, 4, 5].each(function() {
    alert(this);
});

Now, even though this is a very simple example, it does give you an idea of just how powerful of a language it really is, and while it’s not as pretty to look at as ruby, thereof the unfortunate disguise, dismissing JavaScript as a toy language just isn’t viable any more.

Posted in JavaScript, Ruby at October 28th, 2009. No Comments
Tagged with , . Written by: Patrik Hedman

pastbedti.me is using WP-Gravatar