An Introduction to Functional Programming with Python - Part 1
This is the first part of a tutorial series meant to introduce the functional programming paradigm using features built into Python. Most of what I will talk about will be available in both Python 2.7.x and Python 3.x however in this series I will be using Python 3.x and will point out any differences when needed.
I suppose I had better start by answering…
What is a Paradigm?
It’s a way of doing things and as you can see here - there are a lot of them!
If you have completed Vince’s Computing for Maths class then you will have been taught the Python programming language but using the imperative and object oriented paradaigms.
Ok that’s the fancy stuff out of the way, in plain English this means that you tell the computer what to do step-by-step for example consider the following bit of Python:
def calc_average(nums):
"""
This function calculates the average of a list of numbers, it assumes the
list conatins only numbers and is non-empty
Arguments:
- nums: A list of numbers
Outputs:
- The average, a floating point number
"""
sum = 0
for n in nums:
sum += n
return sum/len(nums)
Here we have to tell Python exactly what it needs to do verbaitum
- Create a variable called sum, assign it the value zero.
- Go through each item in the list in turn and add it’s value to the variable sum.
- Divide that by the number of items there were in the list.
Whereas the functional paradigm is part of a family of declarative programming paradgims, where instead of detailing all the steps you simply ‘declare’ what something is or how to transform it into another form. In the case of functional programming this is done (suprisingly) using functions, for example we can rewrite the above as the following.
from functools import reduce
def f_average(nums):
"""
The same as the calc_average function, just in a functional style
"""
sum = reduce(lambda x, y: x + y, nums, 0)
return sum/len(nums)
Python 2.7.x Differences
The
reduce
function was only moved intofunctools
in Python > 3.0 so it doesn’t need to be imported.
Don’t worry too much if you don’t understand the code above we will get around to how exactly this works in later posts, the important point is to note that this style is slightly more abstract and we let python handle some more of the details for us.
Pure vs Impure Functions
There are two types of functions in the world pure and impure. Below are two functions - can you spot the pure function from the impure function?
def f(x):
return x + 1
def g(x):
if isTuesday():
return x + 1
else:
return x
The function g
is the impure function since it depends on the state of the system it is run on.
Depending on if it is Tuesday or not this function may or may not do something, one of the main features
of the functional paradigm and the functional programming langauges (such as Haskell) is that
they deal in pure functions as far as possible.
The function f
is pure, which means given the same arguments will return the same result come rain, come
shine, sleet or snow. If the world is on fire and the socks have declared war on the bananas this function
will behave exactly the same.
The more that you restrict the number of places where the current state of the system affects the behavoir of your code the easier it will be to maintain and extend your program over time.
Well I think that’s it for now, that’s a brief overview of functional programming next time we will take a look at lambdas and higher order functions.