11. Currying in Python
By Bernd Klein. Last modified: 08 Mar 2024.
General Idea
In mathematics and computer science, currying is the technique of breaking down the evaluation of a function that takes multiple arguments into evaluating a sequence of single-argument functions. Currying is also considered to be a design pattern. Currying is also used in theoretical computer science, because it is often easier to transform multiple argument models into single argument models.
Live Python training
See our Python training courses
Origin of the Name
The "Curry" in "Currying" has nothing to do with the spicy curry powder, even though it can make your Python code more spicy. The name is a reference to the logician and mathematician Haskell Brooks Curry, and he is quoted in "THE KLEENE SYMPOSIUM", (Proceedings of the Symposium held June 18-24, 1978 at Madison, Wisconsin. U.S.A.):
Some contemporary logicians call this way of looking at a function “currying”, because I made extensive use of it; but Schonfinkel had the idea some 6 years before I did.
This is why there is also - though seldomly - the name "Schönfinkelisation" being used. There are even further roots of the concept going back to the end of the 19th century and the mathematician Gottlob Frege.
Currying Functions
Currying is the technique of breaking down the evaluation of a function that takes multiple arguments into evaluating a sequence of single-argument functions.
In mathematical notation it looks like this: If we have a function $f$ which takes $n$ arguments, we can 'replace' it by a composition of $n$ functions $f_1, f_2, \ldots f_n$ where each takes only one argument:
we will get the same value x as if we call:
and
An example implemented in Python could look like this:
def f(a1, a2, a3):
return a1 * a2 * a3
def f1(a1):
def f2(a2):
def f3(a3):
return f(a1, a2, a3)
return f3
return f2
for i in range(1, 10):
print(f(i, i+1, i+2), f1(i)(i+1)(i+2))
OUTPUT:
6 6 24 24 60 60 120 120 210 210 336 336 504 504 720 720 990 990
Example BMI
We illustrate this with the function BMI, which we had used in our chapter on functions. We write a curried version of BMI:
def BMI(weight, height):
return weight / height**2
def bmi_curried(height):
def bmi_weight(weight):
return BMI(weight, height)
return bmi_weight
bmi_curried(1.76)(72)
OUTPUT:
23.243801652892564
Using partial
The function partial of the module functools of Python allows you to create partially applied functions. A partially applied function is a new function that is derived from an existing function by fixing a certain number of arguments in advance. The result is a function that can be called with the remaining arguments. We can use it for the commposition of functions.
We demonstrate the way of working in the following examples:
from functools import partial
def f(a1, a2):
return a1 * a2
partial(f, 3)(4)
OUTPUT:
12
from functools import partial
def f(a1, a2, a3):
return a1 * a2 * a3
partial(f, 3, 2)(4)
OUTPUT:
24
partial