Hacker News new | past | comments | ask | show | jobs | submit login
Curried Javascript Functions (crockford.com)
30 points by ccarpenterg on July 19, 2009 | hide | past | favorite | 10 comments



If you already know all about higher-order programming and just want a javascript library with all the haskell/ML-style goodness, I highly recommend O. Steele's Functional library: http://osteele.com/sources/javascript/functional/

If nothing else, then his lambda() implementation with strings should be enough to convince you to use it.


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


Both of our implementations have broken this. Damn you, Javascript this.

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"]


This:

  "foo bar baz thud".splitOnSpaces(); //-> ["foo", "bar", "baz", "thud"]
can be written like this:

  $w("foo bar baz thud")




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: