Side effects: pure and impure functions

Published

2023-07-31

Pure and impure functions

So far, all the functions we’ve written are pure. That is, they accept some argument or arguments, and return a result, behaving like a black box with no interaction with anything outside the box. Example:

def successor(n):
    return n + 1

In this case, there’s an argument, a simple calculation, and the result is returned. This is pure, in that there’s nothing changed outside the function and there’s no observable behavior of the function other than returning the result. This is just like the mathematical function

s(n) = n + 1.

Impure functions

Sometimes it’s useful to implement an impure function. An impure function is one that has side effects. For example, we might want to write a function that prompts the user for an input and then returns the result.

def get_price():
    while True:
        price = float(input("Enter the asking price "
                            "for the item you wish "
                            "to sell: $"))
        if price > 1.00:
            break
        else:
            print("Price must be greater than $1.00!")
    return price

This is an impure function since it has side effects, the side effects being the prompts and responses displayed to the user. That is, we can observe behavior in this function other than its return value. It does return a value, but it exposes other behaviors as well.

Keep side effects to a minimum

Always, always consider what side effects your functions have, and whether such side effects are correct and desirable.

As a rule, it’s best to keep side effects to a minimum (eliminating them entirely if possible). But sometimes it is appropriate to rely on side effects. Just make sure that if you are relying on side effects, that it is correct and by design, and not due to a defect in programming. That is, if you write a function with side effects, it should be because you choose to do so and you understand how side effects may or may not change the state of your program. It should always be a conscious choice and never inadvertent, otherwise you may introduce bugs into your program. For example, if you inadvertently mutate a mutable object, you may change the state of your program in ways you have not anticipated, and your program may exhibit unexpected and undesirable behaviors.

We will take this topic up again, when we get to mutable data types like list and dict in Chapters 10 and 16.

Comprehension check

  1. Write an impure function which produces a side effect, but returns None.

  2. Write a pure function which performs a simple calculation and returns the result.

Original author: Clayton Cafiero < [given name] DOT [surname] AT uvm DOT edu >

No generative AI was used in producing this material. This was written the old-fashioned way.

This material is for free use under either the GNU Free Documentation License or the Creative Commons Attribution-ShareAlike 3.0 United States License (take your pick).