30 October 2007
Currying in JavaScript and Groovy
In the Groovy User Guide, the section "Fixing Closure Arguments to Constant Values Via Currying" gives a quick example of currying using Groovy closures:
def c = { arg1, arg2-> println "${arg1} ${arg2}" }
def d = c.curry("foo")
d("bar")
Basically, you bind one argument to a function taking multiple arguments but don't call the function until the remaining arguments are passed in.
Currying in JavaScript is a do-it-yourself affair. For references see these blog entries (in no particular order): "Curried JavaScript functions", "currying in javascript", "JavaScript currying". These are somewhat verbose and invasive.
The best option is to use prototype 1.6.0's curry function added to Function.prototype:
function sum(a, b) {
return a + b;
}
sum(10, 5) // 15
var addTen = sum.curry(10);
addTen(5) // 15
If you don't want to adopt prototype, you can use the following implementation:
function curry(f, args) {
var thisF = f;
var thisArgs = Array.prototype.slice.apply(args);
return function(args) {
thisArgs = thisArgs.concat(args);
if (thisF.length <= thisArgs.length) {
return thisF.apply(thisF, thisArgs);
} else {
return this;
}
}
}
With the canonical summation test:
function sum(a, b, c) {
return a + b + c;
}
function test() {
sum(1, 2, 3); // 6
x = curry(sum, [1]);
x([2]);
x([3]); // 6
x = curry(sum, [1]);
x([2, 3]); // 6
}
This has not been put through a lot of testing, so YMMV. After looking at the other examples provided in the blogs above, I was astounded how little code it took me to write. As I test more and across multiple browsers, I'm sure it will start bloating...
[ updated 17 Jun 2009 ]
Cleaner implementation from #Javascript on IRC:
Function.prototype.curry = function() {
var func = this, a = Array.prototype.slice.call(arguments, 0);
return function() {
return func.apply(this, a.concat(Array.prototype.slice.call(arguments, 0)));
}
};
[ posted by sstrader on
30 October 2007 at 11:07:30 AM in Programming
]
- Techniques after using Swift for a month posted by sstrader on 26 August 2015 at 11:41:51 PM
- Some thoughts on Ruby after finishing a week (minus one day) of training posted by sstrader on 15 December 2011 at 8:59:30 PM
- Links on the singleton pattern posted by sstrader on 9 December 2011 at 9:19:50 AM
- Phonebot posted by sstrader on 29 October 2011 at 6:37:05 PM
- The labeled break in Java posted by sstrader on 4 September 2011 at 11:27:56 AM
Related entries
Other entries categorized in Programming: