Curried Javascript Functions(javascript.crockford.com)
javascript.crockford.com
Curried Javascript Functions
http://javascript.crockford.com/www_svendtofte_com/code/curried_javascript/index.html
6 comments
Here's an implementation that I think is shorter, simpler to understand, easier to use, and doesn't require modifying existing functions for currification
function curry(fn) {
var wrappedFnMaker = function(accArgs) {
return function() {
var effectiveArgs = accArgs.concat(Array.prototype.slice.call(arguments));
if (effectiveArgs.length >= fn.length) {
return fn.apply(this, effectiveArgs);
} else {
return wrappedFnMaker(effectiveArgs);
}
};
}
return wrappedFnMaker([]);
}
add = curry(function(a,b,c) { return a + b + c; });Here's my take:
function curry(fn, args) {
if (typeof args == "undefined" || args.length < fn.length)
return function() {
if (typeof args == "undefined")
args = [];
return curry(fn, args.concat(Array.prototype.slice.call(arguments)));
};
return fn.apply(this, args);
}
var add = curry(function(a, b, c) { return a + b + c;});Here is curry in php 5.3
function curry(){
$args = func_get_args();
$fn = array_shift($args);
return function() use(&$fn, &$args) {
$nargs = func_get_args();
foreach($nargs as $narg) $args[] = $narg;
return call_user_func_array($fn, $args);
};
}
$add20 = curry(function($a, $b){return $a + $b;}, 20);
echo $add20(5); #25[deleted]
Both of our implementations have broken this. Damn you, Javascript this.
In principle, these two lines of code should always produce the same result:
In principle, these two lines of code should always produce the same result:
foo.bar(1,2)
and foo.bar(1)(2)
And they won't necessarily in our case, if the function uses this.What's the deal with the stuff in the footer of this page? "The original page disappeared a couple of years ago. This is an unauthorized copy." It links to http://www.svendtofte.com/code/curried_javascript/ which I guess is the original article?
Oldie but goodie. If you liked that, you might like this too: [Higher Order Programming in Javascript](http://w3future.com/html/stories/hop.xml)
Currying looks horrible IMHO. It's like goto but worse. Can anyone give a real life example of why it's useful or desired?
Prototype has curry() and bind() methods on functions for some time.
http://prototypejs.org/api/function
String.prototype.splitOnSpaces = String.prototype.split.curry(" "); "foo bar baz thud".splitOnSpaces(); //-> ["foo", "bar", "baz", "thud"]
http://prototypejs.org/api/function
String.prototype.splitOnSpaces = String.prototype.split.curry(" "); "foo bar baz thud".splitOnSpaces(); //-> ["foo", "bar", "baz", "thud"]
This:
"foo bar baz thud".splitOnSpaces(); //-> ["foo", "bar", "baz", "thud"]
can be written like this: $w("foo bar baz thud")
If nothing else, then his lambda() implementation with strings should be enough to convince you to use it.