What is 'Currying'?
Solution 1
Currying is when you break down a function that takes multiple arguments into a series of functions that each take only one argument. Here's an example in JavaScript:
function add (a, b) {
return a + b;
}
add(3, 4); // returns 7
This is a function that takes two arguments, a and b, and returns their sum. We will now curry this function:
function add (a) {
return function (b) {
return a + b;
}
}
This is a function that takes one argument, a
, and returns a function that takes another argument, b
, and that function returns their sum.
add(3)(4);
var add3 = add(3);
add3(4);
The first statement returns 7, like the add(3, 4)
statement. The second statement defines a new function called add3
that will add 3 to its argument. (This is what some may call a closure.) The third statement uses the add3
operation to add 3 to 4, again producing 7 as a result.
Solution 2
In an algebra of functions, dealing with functions that take multiple arguments (or equivalent one argument that's an N-tuple) is somewhat inelegant -- but, as Moses Schönfinkel (and, independently, Haskell Curry) proved, it's not needed: all you need are functions that take one argument.
So how do you deal with something you'd naturally express as, say, f(x,y)
? Well, you take that as equivalent to f(x)(y)
-- f(x)
, call it g
, is a function, and you apply that function to y
. In other words, you only have functions that take one argument -- but some of those functions return other functions (which ALSO take one argument;-).
As usual, wikipedia has a nice summary entry about this, with many useful pointers (probably including ones regarding your favorite languages;-) as well as slightly more rigorous mathematical treatment.
Solution 3
Here's a concrete example:
Suppose you have a function that calculates the gravitational force acting on an object. If you don't know the formula, you can find it here. This function takes in the three necessary parameters as arguments.
Now, being on the earth, you only want to calculate forces for objects on this planet. In a functional language, you could pass in the mass of the earth to the function and then partially evaluate it. What you'd get back is another function that takes only two arguments and calculates the gravitational force of objects on earth. This is called currying.
Solution 4
It can be a way to use functions to make other functions.
In javascript:
let add = function(x){
return function(y){
return x + y
};
};
Would allow us to call it like so:
let addTen = add(10);
When this runs the 10
is passed in as x
;
let add = function(10){
return function(y){
return 10 + y
};
};
which means we are returned this function:
function(y) { return 10 + y };
So when you call
addTen();
you are really calling:
function(y) { return 10 + y };
So if you do this:
addTen(4)
it's the same as:
function(4) { return 10 + 4} // 14
So our addTen()
always adds ten to whatever we pass in. We can make similar functions in the same way:
let addTwo = add(2) // addTwo(); will add two to whatever you pass in
let addSeventy = add(70) // ... and so on...
Now the obvious follow up question is why on earth would you ever want to do that? It turns what was an eager operation x + y
into one that can be stepped through lazily, meaning we can do at least two things
1. cache expensive operations
2. achieve abstractions in the functional paradigm.
Imagine our curried function looked like this:
let doTheHardStuff = function(x) {
let z = doSomethingComputationallyExpensive(x)
return function (y){
z + y
}
}
We could call this function once, then pass around the result to be used in lots of places, meaning we only do the computationally expensive stuff once:
let finishTheJob = doTheHardStuff(10)
finishTheJob(20)
finishTheJob(30)
We can get abstractions in a similar way.
Solution 5
Currying is a transformation that can be applied to functions to allow them to take one less argument than previously.
For example, in F# you can define a function thus:-
let f x y z = x + y + z
Here function f takes parameters x, y and z and sums them together so:-
f 1 2 3
Returns 6.
From our definition we can can therefore define the curry function for f:-
let curry f = fun x -> f x
Where 'fun x -> f x' is a lambda function equivilent to x => f(x) in C#. This function inputs the function you wish to curry and returns a function which takes a single argument and returns the specified function with the first argument set to the input argument.
Using our previous example we can obtain a curry of f thus:-
let curryf = curry f
We can then do the following:-
let f1 = curryf 1
Which provides us with a function f1 which is equivilent to f1 y z = 1 + y + z. This means we can do the following:-
f1 2 3
Which returns 6.
This process is often confused with 'partial function application' which can be defined thus:-
let papply f x = f x
Though we can extend it to more than one parameter, i.e.:-
let papply2 f x y = f x y
let papply3 f x y z = f x y z
etc.
A partial application will take the function and parameter(s) and return a function that requires one or more less parameters, and as the previous two examples show is implemented directly in the standard F# function definition so we could achieve the previous result thus:-
let f1 = f 1
f1 2 3
Which will return a result of 6.
In conclusion:-
The difference between currying and partial function application is that:-
Currying takes a function and provides a new function accepting a single argument, and returning the specified function with its first argument set to that argument. This allows us to represent functions with multiple parameters as a series of single argument functions. Example:-
let f x y z = x + y + z
let curryf = curry f
let f1 = curryf 1
let f2 = curryf 2
f1 2 3
6
f2 1 3
6
Partial function application is more direct - it takes a function and one or more arguments and returns a function with the first n arguments set to the n arguments specified. Example:-
let f x y z = x + y + z
let f1 = f 1
let f2 = f 2
f1 2 3
6
f2 1 3
6
Ben
Currently working at MajorBoost Inc. solving healthcare's communications problems one phone call at a time. Formerly: Worked on HoloLens for Microsoft Was the CTO at a location based games company Tech lead and programmer for Ubisoft and Sony Computer Entertainment Dot-bomb survivor and one of the many people who, independently, created something like AJAX but didn't come up with the cool name.
Updated on February 21, 2022Comments
-
Ben about 2 years
I've seen references to curried functions in several articles and blogs but I can't find a good explanation (or at least one that makes sense!)
-
Alexandre C. almost 13 years[Left as a comment, since it will be useless to the non-mathematicians.] As per the definition of a cartesian closed category, there is a fixed family of adjunctions (naturally parametrized by A) between X -> X x A and X -> X ^ A. The isomorphisms hom(X x A, Y) <-> hom(X, Y^A) are the
curry
anduncurry
functions of Haskell. What is important here is that these isomorphisms are fixed beforehand, and therefore "built-in" into the language. -
Jaider over 11 yearsThere is a nice tutorial here for currying in haskell learnyouahaskell.com/higher-order-functions#curried-functions short comments is that
add x y = x+y
(curried) is different toadd (x, y)=x+y
(uncurried)
-
-
shuckster over 14 yearsAs a curiosity, the Prototype library for JavaScript offers a "curry" function that does pretty much exactly what you've explained here: prototypejs.org/api/function/curry
-
Eric M over 14 yearsI do not get this - you do this: >>> am_quote = curry(display_quote, "Alex Martelli") but then you do this next: >>> am_quote("currying", "As usual, wikipedia has a nice summary...") So you have a function with two args. It would seem that currying should give you three different funcs that you would compose?
-
Eric M over 14 yearsI suppose similar comment to mine above - I have not seen that functional languages restrict functions to taking a single arg. Am I mistaken?
-
Dawid Furman over 14 yearsI am using partial to curry only one parameter, producing a function with two args. If you wanted, you could further curry am_quote to create one that only quoted Alex on a particular subject. The math backgound may be focused on ending up with functions with only one parameter - but I believe fixing any number of parameters like this is commonly (if imprecisely from a math standpoint) called currying.
-
Dawid Furman over 14 years(btw - the '>>>' is the prompt in the Python interactive interpreter, not part of the code.)
-
Dawid Furman over 14 yearsAfter your comment, I searched and found other references, including here on SO, to the difference between "currying" and. "partial application" in response to lots of instances of the imprecise usage I'm familiar with. See for instance: stackoverflow.com/questions/218025/…
-
Eric M over 14 yearsOK. Another questions then. Is the following a true statement? Lambda calculus can be used as a model of functional programming but functional programming is not necessarily applied lambda calculus.
-
Eric M over 14 years@Anon: I just re-read your example and saw that I missed the point. The first arg to display_quote() is after currying to produce am_quote() not present in am_quote(), but the value is carried. If I decompose display_quote() by hand I can produce 3 functions that could be composed to get the same result as display_quote() without fixing the values of any args. The call am_quote = curry(display_quote, "Alex Martelli") seems to me to turn arg 1 of display_quote into a constant string. Is this part of the point of currying, or an artifact of an approach to currying?
-
Alex Martelli over 14 yearsAs wikipedia pages note, most FP languages "embellish" or "augment" lambda calculus (e.g. with some constants and datatypes) rather than just "applying" it, but it's not that close. BTW, what gives you the impression that e.g. Haskell DOESN'T "restrict functions to taking a single arg"? It sure does, though that's irrelevant thanks to currying; e.g.
div :: Integral a => a -> a -> a
-- note those multiple arrows? "Map a to function mapping a to a" is one reading;-). You could use a (single) tuple argument fordiv
&c, but that would be really anti-idiomatic in Haskell. -
Dawid Furman over 14 yearsI think that is exactly the crux of the terminology issue. I, like numerous others out there, was using the term in a way where wiring in arguments was the whole point of currying. Others, I have learned thanks to your question ;-), would instead agree with "artifact of an approach to currying." Good to know this difference in usage exists out there.
-
Eric M over 14 years@Alex - wrt Haskell & arg count, I have not spent a lot of time on Haskell, and that was all a few weeks ago. So it was an easy error to make.
-
Eric M over 14 years@Anon - well it is a quite new and still somewhat strange paradigm to me, so I certainly am not ready to state a personal preference! Knowing there is a difference in usage helps in rying understand the thing.
-
cdmckay almost 12 yearsSo methods in C# would need to be curried before they could be partially applied?
-
Richard Ayotte over 11 yearsNew PrototypeJS curry function link. prototypejs.org/doc/latest/language/Function/prototype/curry/…
-
neontapir about 11 yearsThis sounds like partial application to me. My understanding is that if you apply currying, you can create functions with a single argument and compose them to form more complicated functions. Am I missing something?
-
Strawberry almost 11 yearsIn a practical sense, how can I make use this concept?
-
acarlon over 10 years"This allows functions of several arguments to have some of their initial arguments partially applied." - why is that beneficial?
-
Totti over 10 years@acarlon Functions are often called repeatedly with one or more arguments the same. For example, if you want to
map
a functionf
over a list of listsxss
you can domap (map f) xss
. -
acarlon over 10 yearsThank you, that makes sense. I did a bit more reading and it has fallen into place.
-
nyson over 10 years@Strawberry, say for instance that you have a list of numbers in a
[1, 2, 3, 4, 5]
that you wish to multiply by an arbitrary number. In Haskell, I can writemap (* 5) [1, 2, 3, 4, 5]
to multiply the whole list by5
, and thus generating the list[5, 10, 15, 20, 25]
. -
Strawberry over 10 yearsI understand what the map function does, but I'm not sure if I understand the point you're trying to illustrate for me. Are you saying the map function represents the concept of currying?
-
Doval over 10 years@Strawberry The first argument to
map
must be a function that takes only 1 argument - an element from the list. Multiplication - as a mathematical concept - is a binary operation; it takes 2 arguments. However, in Haskell*
is a curried function, similar to the second version ofadd
in this answer. The result of(* 5)
is a function that takes a single argument and multiplies it by 5, and that allows us to use it with map. -
Doval over 10 years@Strawberry The nice thing about functional languages like Standard ML or Haskell is that you can get currying "for free". You can define a multi-argument function as you would in any other language, and you automatically get a curried version of it, without having to throw in a bunch of lambdas yourself. So you can produce new functions that take less arguments from any existing function without much fuss or bother, and that makes it easy to pass them to other functions.
-
Fuzzy Analysis over 9 years"This allows us to represent functions with multiple parameters as a series of single argument functions" - perfect, that cleared it all up nicely for me. Thanks
-
Danny over 8 yearsI still don't quite understand why you would want to do this.
-
MindJuice over 8 years@neontapir is correct. What Shea described is not currying. It is partial application. If a three-argument function is curried and you call it as f(1), what you get back is not a two-argument function. You get back a one-argument function that returns another one-argument function. A curried function can only ever be passed one argument. The curry function in PrototypeJS is also not currying. It's partial application.
-
MindJuice over 8 yearsI think this answer gets it right in a nice concise way. The "currying" is the process of taking the function of multiple arguments and converting it into a serious of functions that each take a single argument and return a function of a single argument, or in the case of the final function, return the actual result. This can either be done for you automatically by the language, or you can call a curry() function in other languages to generate the curried version. Note that calling a curried function with a parameter is not currying. The currying already happened.
-
lukas_o over 8 years@Strawberry probably for job interviews. ;)
-
SSH This over 8 yearsWell thank you for the explanation, unfortunately the Scheme examples flew right over my head.
-
Kyle Cronin over 8 years@SSHThis Do you know JavaScript? I edited this answer to use JS instead of Scheme.
-
Zeek Aran over 8 yearsI'm a little late, but your code says 3+7=7. Thank you for the explanation though!
-
semicolon about 8 years@Danny well what is more readable and concise?
(lambda x: x + 5)
,(\x -> x + 5)
etc. or(+ 5)
? Because without currying you have to use the former for things likemap (+ 5) [1, 2, 3, 4, 5]
. -
nikk wong over 7 yearsis
func callback
returning itself? It's being called @callback(str)
solet callback = callback(str)
, callback is just the return value offunc callback
-
S2dent over 7 yearsno,
func callback(_:data:)
accepts two parameters, here I only give it one, theString
, so it is waiting for the next one (NSData
), this is why nowlet callback
is another function waiting for data to be passed in -
Kyle Cronin over 7 years@OscarRyz That doesn't look like currying to me. If you want to go with filtering, something like
var greaterThan = x => y => y > x;
would let you curry greaterThan so that you can use it like[1,2,3,4,5].filter(greaterThan(3))
. -
Ahmed Eid about 7 yearsbasically its a use case of closures .. close over one or more argument to make a more specialized function .
-
aw04 about 7 yearsit's useful for caching arguments, maybe you need to call a function many times but the first argument will be the same or maybe that first argument maintains some sort of internal state in a closure
-
Admin about 6 yearsThe best step by step explanation of an inherently sequential process I've seen here, and perhaps the best, most explanatory answer of the lot.
-
whitneyland about 6 years@jonsilver I’d say the opposite, not a good explanation. I agree it’s good at explaining the example posed, but people tend to default to thinking, “yeah perfectly clear but I could have done the same thing another way so what good is currying?” In other words, I wish it had just enough context or explanation to illuminate not just how currying works, but also why it’s not a useless and trivial observation compared to other ways of adding ten.
-
Will Ness over 5 yearsno (to partial evaluation) and no (to currying). this is known as partial application. currying is needed to enable it.
-
camjocotem over 5 yearsCurrying is useful if you find you have a function where you are pass in a parameter which never changes. (Possibly a class with lots of reusable methods?) Instead of always passing in that same parameter, you curry the function to only pass in the parameters that do change
-
Adzz almost 4 yearsThe original question was "what is it", not why is it useful.
-
Abhi over 3 yearsconsider in above answer,if you need to perform add(3,x) multiple times and your first parameter is always same (3) so you no need to call add(3,x) always. you can just call add3(4).
-
david_adler over 3 years"into a series of functions that each take only one argument". I often do a currying like pattern where I create a series of functions so that the top level function is cleaner but not all my functions have just one argument. Is it still currying?
-
tobius about 3 yearsThe curry pattern is a way of applying a fixed argument to an existing function for the purpose of creating a new reusable function without recreating the original function. This answer does an excellent job of demonstrating that.
-
drkvogel about 3 years"we can do at least two things 1. cache expensive operations 2. achieve abstractions in the functional paradigm." This is the "why it's useful" explanation other answers lacked. And I think this answer explained the "what" excellently, too.
-
SacredGeometry over 2 yearsYou gave a lot of examples of how but not a single good argument as to why. Care to expound on that point as it is what I think you alluded to doing at the start of your post?
-
Damian Lattenero about 2 yearsBest twisted answer ever.