First-Class Functions
First-Class Function: A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.
First-Class Citizen: a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include being passed as an argument, returned from a function, modified, and assigned to a variable.
We'll go through some examples to understand what first-class functions are. Note this notebook uses Python 3.6.0.
def cube(number: int) -> int:
""" Return the cube of a number. """
return number ** 3
cube_two = cube(2) # Call the function, set cube_two to the value returned
print(cube) # It says cube is a function
print(cube_two) # The value stored in cube_two
<function cube at 0x05D8CE40> 8
nums = [4, cube(4), cube(4) / cube(4) ** 0.5] # returned values as list elements
print(nums)
cube_dict = {'two_cubed': cube(2), 'five_cubed': cube(5)} # as dict values
print(cube_dict)
[4, 64, 8.0] {'two_cubed': 8, 'five_cubed': 125}
Now we'll see how we can set a variable to the cube() function.
make_cube = cube # Take out those parentheses
print(cube)
print(make_cube) # make_cube points to the cube() function
<function cube at 0x05D8CE40> <function cube at 0x05D8CE40>
Now, the variable make_cube
can be used as a function, like so:
print(cube)
print(make_cube(4))
<function cube at 0x05D8CE40> 64
Functions can be passed as arguments and returned by other functions.
A higher-order function accepts other functions as arguments or returns functions as its result.
map
is an example: it takes a function and an iterable as its arguments, and it applies the function to each value of that iterable and then returns a new iterable of those results.
Here's an example of map
taking a function (int
) as an argument.
str_nums = ['1', '2', '3']
one, two, three = map(int, str_nums) # similar to [int(n) for n in str_nums]
print(str_nums)
print([one, two, three])
['1', '2', '3'] [1, 2, 3]
reduce
is another example: it applies a function of two arguments cumulatively to the items of an iterable. Let's look at an example to see what this means.
from functools import reduce
cumu_diff = reduce(lambda x, y: x - y, [3, 2, 1]) # cumulative difference
print(cumu_diff)
0
Let's create a map-like function (well, kind of).
from typing import Callable, Sequence, Iterable
def map_it(func: Callable, seq: Sequence) -> Iterable:
""" Apply a given function to a sequence and yield the result. """
for item in seq:
yield func(item)
str_nums = ['1', '2', '3']
one, two, three = map_it(int, str_nums) # same as map(int, str_nums)
print([one, two, three])
[1, 2, 3]
Now, let's see how to return a function from another function.
def greet(name: str) -> str:
""" Return a callable function with the given name. """
def print_message():
""" A callable that prints a message to stdout. """
print("Hello, {}!".format(name))
return print_message # returning the function, not calling it
greet_et = greet('E.T.') # greet_et points to print_message()
print(greet)
print(greet_et)
print(greet_et())
<function greet at 0x05D8C858> <function greet.<locals>.print_message at 0x05D8C270> Hello, E.T.! None
Here's another example.
def make_paragraph(tag: str) -> str:
""" Return a callable function with the given tag. """
def wrapper(text: str) -> str:
""" Return text wrapped with a tag. """
return '<{0}>{1}</{0}>'.format(tag, text)
return wrapper
para_one = make_paragraph('p')
print(para_one('This is a small paragraph.')) # returns '<p>This is a small paragraph.</p>'
<p>This is a small paragraph.</p>
In conclusoin, in Python, functions are first-class objects. You can pass functions around as arguments to other functions, store them as dictionary or list values, or have a function return another function.
We've seen several ways to use functions in Python. Happy programming!