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: