What exactly is a higher-order function? Let’s use practical code examples to delve into the concept step by step.
Take Python’s built-in absolute value function abs() as an example. To call this function, use the following code:
>>> abs(-10)
10
But what if we just write abs?
>>> abs
<built-in function abs>
As you can see, abs(-10) is a function call, whereas abs is the function object itself.
To get the result of a function call, we can assign the result to a variable:
>>> x = abs(-10)
>>> x
10
But what if we assign the function object itself to a variable?
>>> f = abs
>>> f
<built-in function abs>
Conclusion: Functions themselves can be assigned to variables; that is, variables can point to functions.
If a variable points to a function, can we call the function through that variable? Let’s verify with code:
>>> f = abs
>>> f(-10)
10
Success! This shows that the variable f now points to the abs function object itself. Calling the abs() function directly is identical to calling the variable f().
So, what exactly are function names? Function names are simply variables that point to functions! For the abs() function, we can completely think of the function name abs as a variable that points to a function object capable of calculating absolute values!
What happens if we make abs point to something else?
>>> abs = 10
>>> abs(-10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
After making abs point to the integer 10, we can no longer call the function using abs(-10)! This is because the variable abs no longer points to the absolute value function but instead points to the integer 10!
Note: You should never write code like this in practice. This example is purely to illustrate that function names are also variables. To restore the abs function, please restart your Python interactive environment.
Side Note: Since the abs function is actually defined in the builtins module, to make the change to the abs variable’s reference take effect in other modules as well, you would need to use: import builtins; builtins.abs = 10.
Since variables can point to functions, and function parameters can accept variables, it follows that a function can accept another function as a parameter. Such functions are called higher-order functions.
A very simple higher-order function:
def add(x, y, f):
return f(x) + f(y)
When we call add(-5, 6, abs), the parameters x, y, and f receive -5, 6, and the abs function object, respectively. According to the function definition, we can deduce the calculation process as follows:
x = -5
y = 6
f = abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
return 11
Let’s verify with code:
def add(x, y, f):
return f(x) + f(y)
print(add(-5, 6, abs)) # Output: 11
Writing higher-order functions means designing functions whose parameters can accept other functions.
do_f_add.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def add(f, *args):
s = [f(arg) for arg in args]
return sum(s)
print(add(abs, 10, -20, 30, -40))
A function that takes other functions as arguments is called a higher-order function. Functional programming refers to this highly abstract programming paradigm.