Skip to content
On this page

Functional Programming

Functions are a built-in feature in Python that allow us to encapsulate code. By breaking down large blocks of code into functions and calling them layer by layer, we can decompose complex tasks into simpler ones. This decomposition can be referred to as procedural programming. Functions are the fundamental units of procedural programming.

Functional Programming is a programming paradigm that, while it can also be categorized under procedural programming, is more closely aligned with mathematical computations.

First, we need to clarify the concepts of Computer and Compute.

At the computer level, the CPU executes instructions for addition, subtraction, multiplication, and division, as well as various conditional and jump instructions. Thus, assembly language is the closest to the computer.

Compute, on the other hand, refers to mathematical calculations. The more abstract the calculation, the further it is from the hardware of the computer.

In programming languages, this translates to lower-level languages being closer to the computer, having lower abstraction and higher execution efficiency, such as C language; conversely, higher-level languages are closer to computation, with higher abstraction and lower execution efficiency, such as Lisp.

Functional programming is a highly abstract programming paradigm. Functions written in pure functional programming languages do not have variables, meaning that for any given function, if the input is fixed, the output is also fixed. These pure functions, which have no side effects, stand in contrast to languages that allow variable usage, where the internal variable states may be uncertain, leading to different outputs for the same input. Thus, such functions exhibit side effects.

One feature of functional programming is that it allows functions themselves to be passed as arguments to other functions, and it also allows for functions to return other functions!

Python provides partial support for functional programming. Since Python allows the use of variables, it is not a pure functional programming language.

Higher-Order Functions

A higher-order function is a function that can take other functions as parameters or return a function as its result. Let's delve into the concept with practical code examples.

Variables Can Point to Functions

For instance, consider Python's built-in absolute value function, abs(). To call this function, you would use the following code:

python
>>> abs(-10)
10

But what happens if we only write abs?

python
>>> abs
<built-in function abs>

Here, abs(-10) is a function call, while abs is the function itself.

To obtain the result of a function call, we can assign it to a variable:

python
>>> x = abs(-10)
>>> x
10

But what if we assign the function itself to a variable?

python
>>> f = abs
>>> f
<built-in function abs>

Conclusion: Functions can indeed be assigned to variables, meaning a variable can point to a function.

If a variable points to a function, can we invoke that function using the variable? Let's verify this with code:

python
>>> f = abs
>>> f(-10)
10

Success! This shows that the variable f now points to the abs function itself. Calling abs() and calling f() are completely identical.

Function Names Are Variables

What, then, is a function name? A function name is essentially a variable that points to a function! For the abs() function, you can consider the function name abs as a variable that points to a function capable of calculating absolute values.

What happens if we point abs to another object?

python
>>> abs = 10
>>> abs(-10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

Once abs points to 10, you can no longer call the function abs(-10)! This is because the variable abs no longer points to the absolute value function but instead points to the integer 10.

Of course, in actual code, you should never do this. This example is solely to illustrate that function names are also variables. To restore the abs function, you would need to restart the Python interactive environment.

Note: Since the abs function is actually defined in the import builtins module, to make the change in the abs variable reference effective in other modules, you would use import builtins; builtins.abs = 10.

Passing Functions as Arguments

Since variables can point to functions and function parameters can accept variables, a function can receive another function as an argument. Such functions are termed higher-order functions.

Here is a simple example of a higher-order function:

python
def add(x, y, f):
    return f(x) + f(y)

When we call add(-5, 6, abs), the parameters x, y, and f receive the values -5, 6, and abs, respectively. According to the function definition, we can deduce the calculation process:

x = -5
y = 6
f = abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
return 11

Let's verify this with code:

python
def add(x, y, f):
    return f(x) + f(y)

print(add(-5, 6, abs))

Writing a higher-order function allows the parameters of the function to accept other functions.

Summary

Functions that take other functions as arguments are called higher-order functions, and functional programming refers to this highly abstract programming paradigm.

Functional Programming has loaded