Self-currying JavaScript functions
by James
I’m telling you, this language keeps surprising me. You’ll need Prototype for this one.
Function.prototype.toSelfCurrying = function(n) {
n = n || this.length;
var method = this;
return function() {
if (arguments.length >= n) return method.apply(this, arguments);
return method.curry.apply(arguments.callee, arguments);
};
};
Make a simple function:
var adder = function(a,b,c) {
return a + b + c;
};
And curry away:
var add = adder.toSelfCurrying();
add(1)(2)(3) // --> 6
add(7,8)(23) // --> 38
Every call to add returns a curried version of add, until the required number of arguments have been supplied. When all arguments are present, you get a return value.
Comments
:) super cool hack. This shows the power of Javascript.
You, sir, are the JavaScript devil. Nice work.
Interesting! You have implemented the curry() function in javascript. Now, can you implement uncurry?
Sweet!. Javascript never seizes to surprise me. Very neat hack!
This is pretty cool! Technically speaking, I think this is “partial application” though and not currying.
Indeed, this is partial application, not currying. Check http://www.haskell.org/haskellwiki/Currying for a quick and nice explanation
Ricardo, thanks for the link. Very helpful, so much so that I actually understood it without ever having used Haskell. Trouble is, Prototype’s curry() method is really partial application, but it’s taken the name so I needed to call my method something else.
Very nice. And I like the picture and color of your blog
Peace
-stephan
In case automatic trackback does not work properly, I will comment here as well. In my post at http://www.barklund.org/blog/2008/02/06/self-partially-applying-javascript-functions/ I discuss and improve on the above as well as implement it in native JavaScript as well as with the MochiKit framework.
But all in all, a very nice trick and a very nice idea. Thanks for the inspiration :)
Just to clear up a couple of things: first, as defined in the Haskell language:
“Currying is the process of transforming a function that takes multiple arguments into a function that takes just a single argument and returns another function if any arguments are still needed.” – Haskell docs
This is what toSelfCurrying() does. However, according to Wikipedia:
“In computer science, currying, invented by Moses Schönfinkel and Gottlob Frege, is the technique of transforming a function that takes multiple arguments into a function that takes a single argument (the other arguments having been specified by the curry).” – Wikipedia
So there’s room for debate. It looks to me (naive as I am) as though Haskell is a special case because all Haskell functions are single-argument functions, so you need to use currying to build multi-argument functions. The discrepancy seems to be over whether pre-set arguments are set with the currying operation. toSelfCurrying() is essentially equivalent to currying in Haskell, while Prototype’s curry() is more in tune with the Wikipedia definition, taking into account JavaScript’s flexibility. Given that the word ‘currying’ is a reference to Haskell B. Curry, I’m inclined to side with the Haskell definition of currying, while referring to Prototype’s curry() as partial application. Apart from anything, partial() and curry() just seem like better nomenclature than curry() and toSelfCurrying().
Second, this blog’s design is the handy work of my colleague Ben Eastaugh (extralogical.net). Funny story, I’d been using this blog template for months before I moved to my current job. A little while after I started, we hired Ben and it emerged he was behind my blog design. Small world.
Actually this concept does more than curry. If curry is transforming a multifunction into a series of single argument function, then this is achieved by the above – among other things. Because as another commenter asks: “how to implement uncurry?”.
But the function returned is all spices! It works with any of 1-n arguments and will just collect and remember how many has been given and return a (n-”given arguments”)-ary function that still can accept less than this value. The resulting function is thus both curried and uncurried.
If you want to create uncurry, which returns a function, that only can accept all arguments (or will invoke the function with only the given arguments), then you simply need to store the function reference on the function instance (as in my implementation) and return this from the given function:
It might not be interesting at all, but it works.
Regarding the discussion of the definition of curry, I was reading more along the lines of the Wikipedia-definition, but I see your point. The Prototype function curry is called partial in MochiKit anyway. We might need a new term for this kind of function, as it somehow defies current definitions. Brave new world ;)
“multifunction” => “multi argument function” of course.
And another funny thing is, that the returned function of course also collect arguments when invoked without any at all:
Very silly, but conceptually sound.
but why should I care about this stuff?! Except for constructing weird syntax function calls or whatever. How does it help me?
Hi. Maybe it is helpful to consider that it is based on λ-calculus, and in λ-calculus, functions can only take one argument. Therefore, all functions in Haskell take one argument. So for functions with more than one argument, currying is necessary.
[...] Self-currying JavaScript functions [...]