4

Working on Secrets of the JavaScript Ninja, I saw the curry function.

Function.prototype.curry = function() {
    var fn = this, args = Array.prototype.slice.call(arguments);
    return function() {
      return fn.apply(this, args.concat(
        Array.prototype.slice.call(arguments)));
    };
  };

Then I tried to use it by currying the split function (which inherited it through the Function.prototype.curry definition.

var splitIt = String.prototype.split.curry(/,\s*/); // split string into array
var results = splitIt("Mugan, Jin, Fuu");
console.log("results", results);    

But [] prints out for the results. Why?

http://jsfiddle.net/2KCP8/

6
  • What does curry do? (I mean, besides giving flavor to the food XD) Commented Dec 27, 2013 at 16:11
  • 1
    Think about what currying does: it binds the first n parameters to specific values. You can still pass values for the remaining parameters when you call the curried function. In your case, you treat split as if it accepted two arguments: a delimiter and the string to act upon. That's not how split works though: it only accepts one argument, the delimiter, and the string it applies to is accessed via "this", the context. Commented Dec 27, 2013 at 16:12
  • @guill: google function currying Commented Dec 27, 2013 at 16:17
  • 1
    Actually that method does not curry a function, it does partially apply it. See en.wikipedia.org/wiki/… for the difference. @KevinMeredith: Currying has nothing to do with lazy evaluation. In Haskell it just is lazy because everything is lazy… Commented Dec 27, 2013 at 16:23
  • 1
    Thanks, @Bergi. After reading that wiki page, I see that curry seems to be a poor name for the above function since it's a partially applied function. Commented Dec 27, 2013 at 16:28

1 Answer 1

3

Your "splitIt" function still expects that this will refer to the string to be split. You haven't arranged for that to be the case here.

Try

var results = splitIt.call("Mugan, Jin, Fuu");
Sign up to request clarification or add additional context in comments.

6 Comments

a.k.a "Mugan, Jin, Fuu".splitIt(). Currying here turned a one-argument function into a zero-argument function (ignoring the fact that this is an implicit argument).
I added a console.log(this) to the curry function. When I called split(string), I saw this = window. However, with splitIt.call(string), it equaled the String.
@KevinMeredith yes that's the expected behavior. If this isn't provided with the method of making the function call, it defaults to the global context. In "strict" mode it'd be undefined.
@Pointy - so harpo's answer will implicitly apply splitIt to the string argument? Whereas your answer will explicitly apply the function to the arguments?
@KevinMeredith yes, that's right. (Well, technically the string is boxed with a String object implicitly, and then that is used as the value of this. But that's an invisible detail.)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.