2 Pure functions

 

In this chapter you will learn

  • why we need pure functions
  • how to pass copies of the data
  • how to recalculate instead of storing
  • how to pass the state
  • how to test pure functions

Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.

—John Carmack

Why do we need pure functions?

In the last chapter we learned about functions that don’t lie. Their signatures tell the whole story about their body. We concluded that these are the functions we can trust: the fewer surprises there are when we code, the fewer bugs there will be in the applications we create. In this chapter we will learn about the most trustworthy of all the functions that don’t lie: a pure function.

Shopping cart discounts

Let’s start by looking at an example that doesn’t use pure functions. We’ll go through its problems and try to solve them intuitively first. Our task is to write a “shopping cart functionality” that is able to calculate discounts based on the current cart contents.

We can design a solution that is a direct encoding of the requirements above. Here’s a diagram of the ShoppingCart class responsible for handling them:

Coding imperatively

Breaking the code

Passing copies of the data

Removing an item

Breaking the code . . . again

Recalculating instead of storing