Functional programming is based on treating a function in the same way as you would a variable or object. So, to start, we should first create a function. This will be a simple function that just adds together two numbers. Please type in the Python Console:
def add(x, y):
"""Simple function returns the sum of the arguments"""
return x + y
This is a very simple function that just returns the sum of its two arguments. Call the function using, e.g.
add(3, 7)
In functional programming, a function is treated in exactly the same way as a variable or an object. This means that a function can be assigned to a variable, e.g. type
a = add
a(3, 7)
We see the same output. Here, we have assigned the function add
to the variable a
. So how does this work?
For variables, you should be comfortable with the idea that a variable refers to a piece of data. For example,
my_num = 10
would create a piece of data (the integer 10
) and will create a variable my_num
which we use to refer to it. When we type
a = my_num
we are creating a new variable a
which points to whatever my_num
was pointing to. Now both a
and my_num
contain (or point to) the same data.
For functional programming, the code of a function is also treated like a piece of data. The code
def add(x, y):
"""Simple function returns the sum of the arguments"""
return x + y
creates a new piece of data (the code to add together x
and y
), and creates a new name add
which points to that code. When we then typed
a = add
we created a new variable a
which refers to the same piece of code data that add
pointed to. Now both a
and add
or point to the same data, i.e. the same code that adds together the two arguments (e.g. add(3, 7)
and a(3, 7)
will call the same code, and give the same result).
This means that “function” is a type, in the same way that “integer”, “string” and “floating point number” are types.
Just as “integer” and “string” have properties, so to does “function”. Type into the Python Console:
add.__[TAB]
(where [TAB]
means that you should press the tab key)
This should show something like
add.__call__ add.__dict__ add.__hash__ add.__reduce_ex__
add.__class__ add.__doc__ add.__init__ add.__repr__
add.__closure__ add.__format__ add.__module__ add.__setattr__
add.__code__ add.__get__ add.__name__ add.__sizeof__
add.__defaults__ add.__getattribute__ add.__new__ add.__str__
add.__delattr__ add.__globals__ add.__reduce__ add.__subclasshook__
(exactly what you see will depend on your version of python)
This is the list of properties (functions and variables) of a function. The most interesting variables are __name__
and __doc__
. Try typing
add.__name__
add.__doc__
From the output, can you guess what these two variables contain?
As well as assigning functions to variables, you can also pass functions as arguments. Type this into the Console:
def call_function(func, arg1, arg2):
"""
Simple function that calls the function 'func' with
arguments 'arg1' and 'arg2', returning the result
"""
return func(arg1, arg2)
call_function(add, 3, 7)
Can you see why we get this output?
The function call_function
takes three arguments. The first is the function to be called. The second two arguments are the arguments that will be passed to that function. The code in call_function
simply calls func
using the arguments arg1
and arg2
. So far, so useless…
However, let us now create another function, called diff
:
def diff(x, y):
"""
Simple function that returns the difference of
its arguments
"""
return x - y
and then type
call_function(diff, 9, 2)
What has happened here?
Now we have passed the function diff
to call_function
, and so func(arg1, arg2)
has used the code contained in diff
, e.g. calculating the difference of the two numbers.
You are probably now wondering how has this helped? Well, let us now change call_function
:
def call_function(func, arg1, arg2):
"""
Simple function that returns the difference of
its arguments
"""
print(f"Calling function {func.__name__} with arguments {arg1} and {arg2}.")
result = func(arg1, arg2)
print(f"The result is {result}")
return result
call_function(add, 3, 7)
Now try:
call_function(diff, 9, 2)
The new call_function
is now doing something useful. It is printing out extra information about our functions, and can do that for any function (which accepts two arguments) that we pass. For example, now type
def multiply(x, y):
"""
Simple function that returns the product of the
two arguments
"""
return x * y
call_function(multiply, 4, 5)