How do I write a function that returns another function?

99,441

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.

Share:
99,441

Related videos on Youtube

Julian Das
Author by

Julian Das

Updated on July 08, 2022

Comments

  • Julian Das
    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 parameter h, and return the volume of a cylinder with height h and radius r.

    I know how to return values from functions in Python, but how do I return another function?

  • sudo
    sudo about 8 years
    So the 10 you passed in is stored somewhere? When does it get garbage-collected?
  • David Hernandez
    David Hernandez over 7 years
  • schoon
    schoon about 6 years
    I 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
    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 by make_cylinder...
  • rmiguelrivero
    rmiguelrivero over 4 years
    from functools import partial add5 = partial(add, 5) Does exactly the same