< March 2010 >
SuMoTuWeThFrSa
  1 2 3 4 5 6
7 8 910111213
14151617181920
21222324252627
28293031   
Wed, 03 Mar 2010:

So bluesmoon wrote a blog entry on function currying in javascript. Read it first, if you've got no idea what I'm talking about.

But the example given there is hardly the *nice* one - you don't need a makeAdder(), you can sprinkle a little bit more magical pixie dust to make a maker. I remembered that I had a better sample lying around from early 2005, but unfortunately it wasn't quoted in my journal entry.

I couldn't find the exact code I wrote back then, but here's a re-do of the same idea.

function curried(f, args, arity)
{

  return function() {
    var fullargs = args.concat(toArray(arguments));
    if(fullargs.length < arity) 
    {
      /* recurse */
      return curry(f).apply(null, fullargs);
    }
    else 
    {
      return f.apply(null, fullargs);
    }
  };

}

function curry(f, arity) 
{
  if(!arity) arity = f.length;

  return function() {
    var args = toArray(arguments);
    if(args.length < arity) 
    {
      return curried(f, args, arity);
    }
    else 
    {
      /* boring */
      return f.apply(null, args);
    }
  };

}

Basically with the help of two closures (the two function() calls without names), I created a generic currying mechanism which can be used as follows.

function add(a,b) { return a+b;}

add = curry(add);

var add1 = add(1);
var c = add1(2);

Now, the hack works because of the arguments object available for use in every javascript function. Also every function, being an object as well, lets you look up the number of arguments (arity) it accepts by default. You can even make a full-class decorator, if you pay more attention to the scope (null, in my examples) passed to the function apply().

Here's the full code example.

--
Things are are rarely simple. The function of good software is to make the complex appear to be simple.
            -- Grady Booch.

posted at: 21:45 | path: /hacks | permalink | Tags: , ,