Nathan Young -X (natyoung - Artizen at Cisco) wrote:
> If I understand your problem statement this is something I'd currently
> solve using closures, is there a way that using currying is
> fundamentally different or is it a different way of thinking about the
> same problem?

At the risk of continuing to stray off-topic, I'll add my two cents worth. Currying is much more limited than closures, but it doesn't involve the overhead that a closure can. A curried function is just that, a function, which is stored once and can be called repeatedly with different arguments. They can be used well as callbacks, but there are many other uses as well. They are not a panacea, and I don't think there is any way they can play well with optional parameters. But they are a nice tool to have available.

It's not hard to add a generic currying function to Javascript. Cory Hudson has a pretty good implementation [1], which I've modified only slightly after some discussions with Sean Catchpole:

    _ = curry_n = function (f, n) {
        if (typeof n == 'undefined') n = f.length;
        return function () {
            if (arguments.length >= n) {
                return f.apply(this, arguments);
            } else {
                var a = [].slice.call(arguments,0);
                return curry_n(
                    function () {
                        return f.apply(this, a.concat([].slice.call(
                                                    arguments,0)));
                    },
                    n-a.length
                );
            }
        };
    }

Using that function (and the "_()" alias for readability, we can define a function like this:

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

And we can call it simply and get the expected answer:

    var sum = add(3, 7);      // => 10

But we can also call it with fewer arguments, and get back a new function:

    var func = add(3);        // => function(b) {return 3 + b;}

This new function can then be called with the additional arguments to get the expected result:

    var sum2 = func(7);       // => 10

This is not limited to a single variable either:

    var mult = _(function(a, b, c) {
        return a * b * c;
    });

    var prod = mult(2, 3, 5); // => 30
    var func2 = mult(2, 3);   // => function(c) {return 6 * c;}
    var prod2 = func2(5);     // => 30
    var func3 = mult(2);      // => function(b, c) {return 2 * b * c;}
    var prod3 = func3(3, 5);  // => 30
    var func4 = func3(3);     // => function(c) {return 6 * c;}
    var prod4 = func4(5);     // => 30


Again, I apologize for going so far off-topic. I haven't yet seen any place where currying would make existing JQuery code any better, but it's a nice thing to keep in mind when needed.

  -- Scott

[1] http://www.coryhudson.com/blog/2007/03/10/javascript-currying-redux/


Reply via email to