I quite often see on the Internet various complaints that other peoples examples of currying are not currying, but are actually just partial application.
I've not found a decent explanation of what partial application is, or how it differs from currying. There seems to be a general confusion, with equivalent examples being described as currying in some places, and partial application in others.
Could someone provide me with a definition of both terms, and details of how they differ?
Interesting question. After a bit of searching, "Partial Function Application is not currying" gave the best explanation I found. I can't say that the practical difference is particularly obvious to me, but then I'm not an FP expert...
Another useful-looking page (which I confess I haven't fully read yet) is "Currying and Partial Application with Java Closures".
It does look like this is widely-confused pair of terms, mind you.
Currying is a function of one argument which takes a function
f
and returns a new functionh
. Note thath
takes an argument fromX
and returns a function that mapsY
toZ
:Partial application is a function of two(or more) arguments which takes a function
f
and one or more additional arguments tof
and returns a new functiong
:The confusion arises because with a two-argument function the following equality holds:
Both sides will yield the same one-argument function.
The equality is not true for higher arity functions because in this case currying will return a one-argument function, whereas partial application will return a multiple-argument function.
The difference is also in the behavior, whereas currying transforms the whole original function recursively(once for each argument), partial application is just a one step replacement.
Source: Wikipedia Currying.
In writing this, I confused currying and uncurrying. They are inverse transformations on functions. It really doesn't matter what you call which, as long as you get what the transformation and its inverse represent.
Uncurrying isn't defined very clearly (or rather, there are "conflicting" definitions that all capture the spirit of the idea). Basically, it means turning a function that takes multiple arguments into a function that takes a single argument. For example,
Now, how do you turn this into a function that takes a single argument? You cheat, of course!
Notice that plus now takes a single argument (that is composed of two things). Super!
What's the point of this? Well, if you have a function that takes two arguments, and you have a pair of arguments, it is nice to know that you can apply the function to the arguments, and still get what you expect. And, in fact, the plumbing to do it already exists, so that you don't have to do things like explicit pattern matching. All you have to do is:
So what is partial function application? It is a different way to turn a function in two arguments into a function with one argument. It works differently though. Again, let's take (+) as an example. How might we turn it into a function that takes a single Int as an argument? We cheat!
That's the function that adds zero to any Int.
adds 1 to any Int. Etc. In each of these cases, (+) is "partially applied".
For me partial application must create a new function where the used arguments are completely integrated into the resulting function.
Most functional languages implement currying by returning a closure: do not evaluate under lambda when partially applied. So, for partial application to be interesting, we need to make a difference between currying and partial application and consider partial application as currying plus evaluation under lambda.
The difference between curry and partial application can be best illustrated through this following JavaScript example:
Partial application results in a function of smaller arity; in the example above,
f
has an arity of 3 whilepartial
only has an arity of 2. More importantly, a partially applied function would return the result right away upon being invoke, not another function down the currying chain. So if you are seeing something likepartial(2)(3)
, it's not partial application in actuality.Further reading:
Currying is converting a single function of n arguments into n functions with a single argument each. Given the following function:
When curried, becomes:
In order to get the full application of f(x,y,z), you need to do this:
Many functional languages let you write
f x y z
. If you only callf x y
or f(x)(y) then you get a partially-applied function—the return value is a closure oflambda(z){z(x(y))}
with passed-in the values of x and y tof(x,y)
.One way to use partial application is to define functions as partial applications of generalized functions, like fold: