views:

2595

answers:

7

I don't think I've grokked currying yet. I understand what it does, and how to do it. I just can't think of a situation I would use it.

Where are you using currying in javascript (or where are the main libraries using it)? DOM manipulation or general application development examples welcome.

EDIT: One of the answers mentions animation. Functions like "slideUp", "fadeIn" take an element as an arguments and are normally a curried function returning the high order function with the default "animation function" built-in. Why is that better than just applying the higher-up function with some defaults?

Oh and are there any drawbacks to using it?

Cheers.

EDIT: As requested here are some good resources on javascript currying:

I'll add more as they crop up in the comments.

A: 

As for libraries using it, there's always Functional.

When is it useful in JS? Probably the same times it is useful in other modern languages, but the only time I can see myself using it is in conjunction with partial application.

Hank Gay
Thanks Hank - please can you expand on when it is useful in general?
Dave Nolan
+1  A: 

I would say that, most probably, all the animation library in JS are using currying. Rather than having to pass for each call a set of impacted elements and a function, describing how the element should behave, to a higher order function that will ensure all the timing stuff, its generally easier for the customer to release, as public API some function like "slideUp", "fadeIn" that takes only elements as arguments, and that are just some curried function returning the high order function with the default "animation function" built-in.

gizmo
Why is it better to curry the higherup function rather than simply call it with some defaults?
Dave Nolan
Because it's highly more modular to be able to curry a "doMathOperation" with an addition/multiplication/square/modulus/other-calucation at wish than to imagine all the "default" that the higher function could support.
gizmo
+1  A: 

It's no magic or anything... just a pleasant shorthand for anonymous functions.

partial(alert, "FOO!") is equivalent to function(){alert("FOO!");}

partial(Math.max, 0) corresponds to function(x){return Math.max(0, x);}

The calls to partial (MochiKit terminology. I think some other libraries give functions a .curry method which does the same thing) look slightly nicer and less noisy than the anonymous functions.

Marijn
+1  A: 

I found functions that resemble python's functools.partial more useful in JavaScript:

function partial(fn) {
  return partialWithScope.apply(this,
    Array.prototype.concat.apply([fn, this],
      Array.prototype.slice.call(arguments, 1)));
}

function partialWithScope(fn, scope) {
  var args = Array.prototype.slice.call(arguments, 2);
  return function() {
    return fn.apply(scope, Array.prototype.concat.apply(args, arguments));
  };
}

Why would you want to use it? A common situation where you want to use this is when you want to bind this in a function to a value:

var callback = partialWithScope(Object.function, obj);

Now when callback is called, this points to obj. This is useful in event situations or to save some space because it usually makes code shorter.

Currying is similar to partial with the difference that the function the currying returns just accepts one argument (as far as I understand that).

Armin Ronacher
+1  A: 

@Hank Gay

In response to EmbiggensTheMind's comment:

I can't think of an instance where currying—by itself—is useful in JavaScript; it is a technique for converting function calls with multiple arguments into chains of function calls with a single argument for each call, but JavaScript supports multiple arguments in a single function call.

In JavaScript—and I assume most other actual languages (not lambda calculus)—it is commonly associated with partial application, though. John Resig explains it better, but the gist is that have some logic that will be applied to two or more arguments, and you only know the value(s) for some of those arguments.

You can use partial application/currying to fix those known values and return a function that only accepts the unknowns, to be invoked later when you actually have the values you wish to pass. This provides a nifty way to avoid repeating yourself when you would have been calling the same JavaScript built-ins over and over with all the same values but one. To steal John's example:

String.prototype.csv = String.prototype.split.partial(/,\s*/);
var results = "John, Resig, Boston".csv();
alert( (results[1] == "Resig") + " The text values were split properly" );
Hank Gay
A: 

Thanks for the answers.

So currying and partial application in general are convenience techniques.

If you are frequently "refining" a high-level function by calling it with same configuration, you can curry (or use Resig's partial) the higher-level function to create simple, concise helper methods.

Cheers!

Dave Nolan
A: 

Here's an example.

I'm instrumenting a bunch of fields with JQuery so I can see what users are up to. The code looks like this:

$('#foo').focus(trackActivity);
$('#foo').blur(trackActivity);
$('#bar').focus(trackActivity);
$('#bar').blur(trackActivity);

(For non-JQuery users, I'm saying that any time a couple of fields get or lose focus, I want the trackActivity() function to be called. I could also use an anonymous function, but I'd have to duplicate it 4 times, so I pulled it out and named it.)

Now it turns out that one of those fields needs to be handled differently. I'd like to be able to pass a parameter in on one of those calls to be passed along to our tracking infrastructure. With currying, I can.

William Pietri