What is 'Currying'?

201,157

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
Share:
201,157
Ben
Author by

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, 2022

Comments

  • Ben
    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.
      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 and uncurry functions of Haskell. What is important here is that these isomorphisms are fixed beforehand, and therefore "built-in" into the language.
    • Jaider
      Jaider over 11 years
      There is a nice tutorial here for currying in haskell learnyouahaskell.com/higher-order-functions#curried-function‌​s short comments is that add x y = x+y (curried) is different to add (x, y)=x+y (uncurried)
  • shuckster
    shuckster over 14 years
    As 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
    Eric M over 14 years
    I 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
    Eric M over 14 years
    I 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
    Dawid Furman over 14 years
    I 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
    Dawid Furman over 14 years
    (btw - the '>>>' is the prompt in the Python interactive interpreter, not part of the code.)
  • Dawid Furman
    Dawid Furman over 14 years
    After 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
    Eric M over 14 years
    OK. 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
    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
    Alex Martelli over 14 years
    As 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 for div &c, but that would be really anti-idiomatic in Haskell.
  • Dawid Furman
    Dawid Furman over 14 years
    I 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
    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
    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
    cdmckay almost 12 years
    So methods in C# would need to be curried before they could be partially applied?
  • Richard Ayotte
    Richard Ayotte over 11 years
  • neontapir
    neontapir about 11 years
    This 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
    Strawberry almost 11 years
    In a practical sense, how can I make use this concept?
  • acarlon
    acarlon over 10 years
    "This allows functions of several arguments to have some of their initial arguments partially applied." - why is that beneficial?
  • Totti
    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 function f over a list of lists xss you can do map (map f) xss.
  • acarlon
    acarlon over 10 years
    Thank you, that makes sense. I did a bit more reading and it has fallen into place.
  • nyson
    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 write map (* 5) [1, 2, 3, 4, 5] to multiply the whole list by 5, and thus generating the list [5, 10, 15, 20, 25].
  • Strawberry
    Strawberry over 10 years
    I 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
    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 of add 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
    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
    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
    Danny over 8 years
    I still don't quite understand why you would want to do this.
  • MindJuice
    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
    MindJuice over 8 years
    I 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
    lukas_o over 8 years
    @Strawberry probably for job interviews. ;)
  • SSH This
    SSH This over 8 years
    Well thank you for the explanation, unfortunately the Scheme examples flew right over my head.
  • Kyle Cronin
    Kyle Cronin over 8 years
    @SSHThis Do you know JavaScript? I edited this answer to use JS instead of Scheme.
  • Zeek Aran
    Zeek Aran over 8 years
    I'm a little late, but your code says 3+7=7. Thank you for the explanation though!
  • semicolon
    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 like map (+ 5) [1, 2, 3, 4, 5].
  • nikk wong
    nikk wong over 7 years
    is func callback returning itself? It's being called @ callback(str) so let callback = callback(str), callback is just the return value of func callback
  • S2dent
    S2dent over 7 years
    no, func callback(_:data:) accepts two parameters, here I only give it one, the String, so it is waiting for the next one (NSData), this is why now let callback is another function waiting for data to be passed in
  • Kyle Cronin
    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
    Ahmed Eid about 7 years
    basically its a use case of closures .. close over one or more argument to make a more specialized function .
  • aw04
    aw04 about 7 years
    it'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
    Admin about 6 years
    The 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
    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
    Will Ness over 5 years
    no (to partial evaluation) and no (to currying). this is known as partial application. currying is needed to enable it.
  • camjocotem
    camjocotem over 5 years
    Currying 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
    Adzz almost 4 years
    The original question was "what is it", not why is it useful.
  • Abhi
    Abhi over 3 years
    consider 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
    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
    tobius about 3 years
    The 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
    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
    SacredGeometry over 2 years
    You 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
    Damian Lattenero about 2 years
    Best twisted answer ever.