How do I write a function that returns another function?
Solution 1
Try this, using Python:
import math
def make_cylinder_volume_func(r):
def volume(h):
return math.pi * r * r * h
return volume
Use it like this, for example with radius=10
and height=5
:
volume_radius_10 = make_cylinder_volume_func(10)
volume_radius_10(5)
=> 1570.7963267948967
Notice that returning a function was a simple matter of defining a new function inside the function, and returning it at the end - being careful to pass the appropriate parameters for each function. FYI, the technique of returning a function from another function is known as currying.
Solution 2
Using lambdas, also known as anonymous functions, you can abstract out the volume
function inside the make_cylinder_volume_func
to a single line. In no way different from Óscar López's answer, the solution using lambda is still in a sense 'more functional'.
This is how you can write the accepted answer using a lambda expression:
import math
def make_cylinder_volume_fun(r):
return lambda h: math.pi * r * r * h
And then call as you'd any other curried function:
volume_radius_1 = make_cylinder_volume_fun(1)
volume_radius_1(1)
=> 3.141592653589793
Solution 3
Just want to point out that you can do this with pymonad
import pymonad
@pymonad.curry
def add(a, b):
return a + b
add5 = add(5)
add5(4)
9
Solution 4
I know I am too late to the party, but I think you might find this solution interesting.
from math import pi
from functools import partial
def cylinder_volume(r, h):
return pi * r * r * h
make_cylinder_with_radius_2 = partial(cylinder_volume, 2)
make_cylinder_with_height_3 = partial(cylinder_volume, h=3)
print(cylinder_volume(2, 3)) # 37.6991118431
print(make_cylinder_with_radius_2(3)) # 37.6991118431
print(make_cylinder_with_height_3(2)) # 37.6991118431
Here is documentation about how partial
works.
Related videos on Youtube
Julian Das
Updated on July 08, 2022Comments
-
Julian Das almost 2 years
In Python, I'd like to write a function
make_cylinder_volume(r)
which returns another function. That returned function should be callable with a parameterh
, and return the volume of a cylinder with heighth
and radiusr
.I know how to return values from functions in Python, but how do I return another function?
-
Paul Collingwood over 11 years
-
-
sudo about 8 yearsSo the
10
you passed in is stored somewhere? When does it get garbage-collected? -
David Hernandez over 7 years@sudo take a look at en.wikipedia.org/wiki/Closure_(computer_programming)
-
schoon about 6 yearsI realise you are answering what was requested, but for the sake of my understanding, if
lambda h:
was removed would the function work the same? -
DaveIdito about 6 years@schoon No it won't work in this case. This is actually a very interesting case to highlight the idea of 'variable scoping' and function currying (which basically relies on varibale scoping). The reason why it doesn't work (in my example) is because the
return
will try to evaluate the result before returning, and because it's a bunch of variables, it will return some float value (try returning a function and it will work).lambda
tellsl that the following code shouldn't be evaluated and also that the scope of variable r will be preserved in functions returned bymake_cylinder..
. -
rmiguelrivero over 4 years
from functools import partial add5 = partial(add, 5)
Does exactly the same