JavaScript currying
Currying in JavaScript, in my own opinion, leads to clever programming. It is also one of the places in JavaScript where functional programming wins over object oriented practices. Sometime last year Dan Webb wrote a post on callbacks and partial application which essentially uses a pattern technique called currying. In his article, he gives a few examples which essentially prove the usefulness of currifed JavaScript.
callbacks in JavaScript (paraphrased code from danwebb.net)
// callback function declaration
function update(id) {
return function(resp) {
document.getElementById(id).innerHTML = resp.responseText;
};
}
// currying in action
request('comment.php', update('item'));
Obviously there are implications here that currying is clever. So on that same token, I figured it would have been just as useful to write my very own JavaScript currier function. This was written nearly the same time Dan’s article came out, but I’m just now getting to sharing it. It looks like this:
a curry function in JavaScript
function curry (fn, scope) {
var scope = scope || window;
var args = [];
for (var i=2, len = arguments.length; i < len; ++i) {
args.push(arguments[i]);
};
return function() {
fn.apply(scope, args);
};
}
This can be used in many ways. Here are a few:
practical usage of the curry function
/* add a curried function bound to a click event */
var el = document.getElementById('my-element');
el.addEventListener('click', curry(sayHello, el, 'Hello World from Dustin'), false);
function sayHello(msg) {
alert(msg+'\n You clicked on '+this.id);
}
/* or to use it in the callback example */
request('comment.php', curry(update, window, 'item'));
/*
or let's say you're subscribing
to a custom event (eg. YAHOO.util.CustomEvent)
*/
var myEvent = YAHOO.util.CustomEvent(
'shake it up',
this,
true,
YAHOO.util.CustomEvent.FLAT
);
myEvent.subscribe(curry(doSomeThingCool, null, 'that', 'requires', 'these', args'));
You can also do a google search for javascript + curry for further information on other implemenations (no, I was not the first one to do this). Cheers.




February 26th, 2007 at 1:19 am
The implementation of find/fold/map functions in Javascript
http://invisibleblocks.wordpress.com/2007/02/23/functional-programming-in-javascript-and-ruby/
February 26th, 2007 at 7:50 am
Just letting you know you’ve a couple of typos in that code, missing \ and missing ‘. I tried to email you rather than leaving a comment, but couldn’t actually find an email address or a contact form anywhere obvious….?
February 26th, 2007 at 7:52 am
Oh, and the link to “callbacks and partial application” 404s :-)
February 26th, 2007 at 8:33 am
[...] Dustin Diaz has written a post on the pattern technique called currying. For those of you not familiar with currying, it’s basically the transformation of an input into a new function. Dustin’s opinion is that: [currying]…leads to clever programming. It is also one of the places in JavaScript where functional programming wins over object oriented practices. [...]
February 26th, 2007 at 8:43 am
Nice writeup. This is the first time I hear of the term!
Regarding the curry function implementation: why not
sliceinstead of the for loop?February 26th, 2007 at 8:51 am
Come to think of it — your implementation is almost the same as
Function.prototype.bindin the Prototype framework:February 26th, 2007 at 9:44 am
@Seb: Sometimes wordpress does funny stuff to my code… for instance it stripped out the backslash. Anyway, if i was worried about typos, I’d be out of the blogging business ;)
@Mislav: arguments is not a true array like you might think. The slice method will not work. Go ahead and try it. And yeah, the bind method does look similar, I just don’t know why it’s called bind… None the less Prototype has many programming idioms that other libraries don’t - and that’s pretty cool.
February 26th, 2007 at 9:57 am
Corrected link.
February 26th, 2007 at 11:54 am
@Dustin: slice() will work if you call it the way Mislav does. I use that all the time. In fact, isn’t my entry on doing something similar the reason why you had me down as a mad tramp in your podcast? :)
February 26th, 2007 at 12:49 pm
I’d guess the reason they call it ‘bind’ in prototype is because it’s not a general currying function (nor is the curry function presented here.) It’s purpose is to treat a function as a method of a given object (binding the function to the object)
Currying is supposed to be used to assign fixed values to the first ‘n’ arguments of a multi-argument function. It’s nothing to do with method-calls (’scope’ is irrelevant.) Also, currying is not supposed to be used to create zero-argument functions.
http://en.wikipedia.org/wiki/Currying
Prototype’s ‘bind’ function is actually pretty close to general currying as it allows additional arguments to be passed in to the curried function by using
args.concat($A(arguments))Also, as the ‘bind’ implementation shows - you don’t need to check for a valid ’scope’ before calling apply as ‘apply’ will do the checks for you (using global-scope if ’scope’ is null or undefined.)
Final anally-retentive point:
scope || windowevaluates to window for the number 0, boolean false and the empty-string. Any one of them could be a legitimate object to call a method on.February 26th, 2007 at 2:16 pm
@Dan & Mislav: Nice way to slice the arguments, unfortunately it won’t work in ie5 - call() isn’t supported. Of course apply() doesn’t work in ie5 either so I’m no better off really and sadly I do need to support ie5. Curse you ie5.
February 26th, 2007 at 3:24 pm
I spoke to soon
February 27th, 2007 at 12:22 am
Dustin, looks like Mislav just pasted in some code from the wikipedia article on Currying…
http://en.wikipedia.org/wiki/Currying#JavaScript
Slicing arguments probably works :D
February 27th, 2007 at 6:44 am
Be careful with the closure you are creating!
PS: this is very similar to the Delegate technique in Flash Actionscript (which has adds a technique to avoid the closure).
February 27th, 2007 at 7:19 am
My own implementation which allows a function to be re-called without having to re-call curry, ie:
It requires two extra functions, Array.copy and Array.each:
February 27th, 2007 at 7:22 am
sorry, got stripped…
February 27th, 2007 at 7:22 am
I have my own version of currying in javascript , accompanied with a stress test that…well reveals a lot .
http://bosky101.blogspot.com/2006/10/edited-currying-in-javascript-stress.html
Keep Clicking,
Bhasker V Kode
February 27th, 2007 at 7:31 am
Hey Mr.Diaz,
Love your screencasts,and long time reader of the blog as well .
Now from the examples youve given -i really wonder if you need to curry for UI . at besti think it could be used for non-window painting events .(which means that each time you pass through the recusion, the window needs to repaint ) and ive faced cases where its even caused browser standstills and crashes.
Instead how about a deferred event ?! i have another function called the IdempotentEvent which might be most suited for UI and DOM hacking . Its over at :
http://bosky101.blogspot.com/2007/02/adding-idempotent-event-handling-to.html
Keep Clicking,
Bhasker V Kode
Keep Clicking,
Bhasker V Kode
February 27th, 2007 at 9:13 am
Thank’s for this Dustin! After reading this I went and made a currying function for adding functions to events that had the event function auto-fixed.
February 27th, 2007 at 9:22 am
A more indepth rendition of currying can be found at: http://www.svendtofte.com/code/curried_javascript/
March 1st, 2007 at 8:00 am
[...] Dustin Diaz has a nice entry on currying in JavaScript a technique used often in languages such as LISP, Perl, and many others. [...]
March 2nd, 2007 at 5:32 pm
[...] JavaScript currying [...]
March 2nd, 2007 at 11:18 pm
[...] JavaScript currying (tags: javascript currying *i_learning*) [...]
March 10th, 2007 at 2:01 am
[...] Currying in JavaScript is all the rage. There’s no shortage of code examples on how to do it. Regardless, currying is still a topic that many of us have a hard time truly wrapping our brains around. Let’s dig a little deeper. When we come out on the other side, we’ll have a little syntactic sugar for automagically currying functions that most of us have never seen before. [...]
March 16th, 2007 at 11:56 pm
[...] These delegates are very useful. In the official documentation the block of code they define is called an anonymous method but I will also call it is a closure which are used heavily in Javascript and other dynamic scripting languages. In Javascript you use a closure to curry variables into an anonymous function. I am learning I can save a good deal of time with this style of coding. [...]
April 5th, 2007 at 12:41 am
[...] As I stated earlier, dsHistory is pretty easy to use and was designed so that functions would be called as a user moved forwards and backwards through the history. Since it is based on functions, I highly recommend you use a currying helper function such as Dustin Diaz’s curry() or, my personal favorite, Prototype’s bind(). Use whatever works best for you. Anyway, check out the example code below. [...]
April 15th, 2007 at 12:03 pm
[...] Since it is based on functions, I highly recommend you use a currying helper function such as Dustin Diaz’s curry() or, my personal favorite, Prototype’s bind(). Use whatever works best for you. Anyway, check out the example code below. [...]
May 29th, 2007 at 12:58 am
What is the recommended approach for avoiding memory leaks with currying when using a helper funtion like this?
Since this will result in closures, IE is leaking a lot of memory.
(Please don’t say ‘Use Firefox’).
Einar
July 10th, 2007 at 11:52 am
Einar, use Opera :))
November 4th, 2007 at 5:24 pm
[...] There are a lot of curry functions examples out there so I decided I’d share mine as well. The code was inspired by a blog posting from Dustin Diaz who was in turn inspired by one from Dan Webb. Those posts can probably do an overall better job of explaining currying than I can so I’m not going to go in to the idea of currying in any great detail. So I’ll just say the currying pattern is useful for attaching data to a function in a way that avoids using global variables and simplifies the use of closure. [...]