It would be very helpful, if someone explains the working of a curry function. I have read many examples, but not able to grasp it properly. Is it anyhow related to closure.
Asked
Active
Viewed 1,827 times
4
-
Too broad: There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs. – thefourtheye Mar 07 '15 at 06:33
-
1Look here for more info: http://stackoverflow.com/questions/36314/what-is-currying – A.J. Uppal Mar 07 '15 at 06:36
-
1Yes, curried functions when partially applied return closures. For example, `function add(a) { return function (b) { return a + b; }; }` is a function which returns the closure `function (b) { return a + b; }` which closes over the upvalue `a`. However, trivially all functions in JavaScript are closures. Read the following answer for more details: http://stackoverflow.com/a/12931785/783743 – Aadit M Shah Mar 07 '15 at 06:57
-
@Aadit I've seen currying listed as one of the important features of a functional languages. Can anyone please give me a solid reason to use a curry function. – Rudra Mar 07 '15 at 07:26
-
1Curry is useful in primarily functional languages like Haskell and OCaml where all functions are curried by default. For example, you could either write `filter odd [1,2,3,4,5]` or `let filterOdd = filter odd in filterOdd [1,2,3,4,5]`. However, it doesn't make much sense in JavaScript. Instead, in JavaScript partial application using `Function.prototype.bind` makes more sense. Here's the difference: http://stackoverflow.com/questions/218025/what-is-the-difference-between-currying-and-partial-application. Currying is a method of enabling partial application. – Aadit M Shah Mar 07 '15 at 07:31
-
Please ask about a specific `curry` implementation. Currying in general is a technique that is not necessarily related to closures. – Bergi Feb 24 '16 at 14:14
1 Answers
6
Currying is just technique, that can make use of any language feature (e.g. closures) to achieve the desired result, but it is not defined what language feature has to be used. As of that currying does not require to make use of closures (but in most of the cases closures will be used)
Here a little example of the usage of currying, with and without the usage of closure.
With the use closure:
function addition(x,y) {
if (typeof y === "undefined" ) {
return function (y) {
return x + y;
}
}
return x + y;
}
var additionRemaining = addition(3); // Currying
additionRemaining(5);//add 5 to 3
With the use of new Function
instead of closure (partial evaluation):
function addition(x,y) {
if (typeof y === "undefined" ) {
return new Function('y','return '+x+' + y;');
}
return x + y;
}
var additionRemaining = addition(3); // Currying
additionRemaining(5);//add 5 to 3

t.niese
- 39,256
- 9
- 74
- 101
-
1As far as I understand, your second example using `new Function' is also using closure. – Rudra Mar 07 '15 at 06:53
-
1@Ruda: No the second example creates a function that is equal to `function(y) { return 3 + y;}` the `3` is hardcoded into the returned function, so this function does not access variables that are out of its scope. If you would write `return new Function('y','console.log(x); return '+x+' + y;');` you can see that `x` is not defined in the scope of that function. – t.niese Mar 07 '15 at 06:54
-
@t Got the difference, but still not clear about other(easier) ways of creating a curry function. Suppose, I have a function taking 3 parameters, in that case i have to create 3 functions nested in a hierarchy. And why should I even create a curry function?. – Rudra Mar 07 '15 at 07:03
-
1You should mention that the second example is a form of currying by [partial evaluation](https://en.wikipedia.org/wiki/Partial_evaluation). You should also mention that it can only be used safely for primitive types like numbers, booleans, strings, null and undefined. For objects and arrays you should use `JSON.stringify`. For functions there's no safe way to convert it into a string. For example, native functions when stringified usually return `function () { [native code] }`, which obviously cannot be used in partial evaluation. Hence, I would rather stay away from such solutions. – Aadit M Shah Mar 07 '15 at 07:05
-
Your first example can be made more elegant as follows: `function addition(x, y) { if (arguments.length < 2) return function (y) { return x + y }; return x + y; }`. Checking `arguments.length` is better than testing whether `y` is undefined because people could call `addition(3, undefined)` for example. – Aadit M Shah Mar 07 '15 at 07:10
-
1@AaditMShah Wouldn't `arguments.length` be also `2` in your example above? – Teemu Mar 07 '15 at 07:13
-
@AaditMShah Hmm, thought it was clear that both examples are currying. I just wanted to say, that currying does not imply that closures are used. Currying is just technique, that can use any language feature (e.g. closures) to achieve the desired result, but it is not defined what language feature has to be used. Sure partial evaluation cannot be used every where (and i even doesn't recommend it), but it doesn't make use of closure. – t.niese Mar 07 '15 at 07:13
-
-
Instead of `arguments.length`, why not use `addition.length`? That will return the number of arguments the function takes. In this case, that's 2. – Kevin Ghadyani Oct 08 '17 at 05:28
-
@Sawtaytoes it's about the arguments that are passed to the function not the number of arguments the function takes by its signature. The idea is that if you only pass - in this case - the first of two arguments, that a new function is returned saving the first argument. `addition.length` would always be `2`, no matter if one or two arguments are passed. – t.niese Oct 08 '17 at 07:39
-