Recap: Java/OOP vs Pure Functions

Introduction

When I began this section of the book and video series, I showed that these were the two most complicated type declarations I found in over 150,000 lines of production Java code:

SortedMap<String, Integer> wordCountMap = new TreeMap();
public Class<?> getColumnClass(int columnIndex) {

Conversely, as you saw in the Word Count example, as I sketched out that application in Scala using pure functions, I’m already working with data types like these:

Seq[String]
VectorMap[String, Int]   // or: MapSortedByValueDesc[Word, Count]

This is a hint that in Scala we use types a lot more than developers are used to using in Java/OOP.

As someone who’s interested in helping programmers who want to learn more about Scala, it’s important to acknowledge that this is a different world than Java/OOP. In the Java world you generally only work with types like this if you’re a library developer, but in the Scala world, developers at all levels work with them. So I think it’s important to acknowledge this difference.

That being said, I’ll ask: Did you find the Word Count example hard to follow? I suspect — and hope — it wasn’t hard to follow. As you saw, I just sketched out a series of pure functions and their type signatures.

Benefits

There are a lot of benefits to this approach of working with only pure functions, immutable variables, and immutable data structures. First, here’s some of what you’ve already seen:

  • You write pure functions.
  • Writing pure functions is about as easy as it gets. You don’t have to worry about the state of the entire application, all you have to think about is (a) what comes in, and (b) what goes out.
  • Because of those attributes, you can sketch solutions just like I did. Just sketch out the solution as a series of pure functions, and then fill in the function bodies.
  • You can trust the type signatures of pure functions, they cannot lie. Their signatures tell you what’s going on.
  • Because of that, you can trust pure functions that other developers write.
  • I’ve only briefly touched on this so far, but if you look at a pure function’s signature and see Option, Try, or Either as the return type, you immediately know, “Something can go wrong here.” (More on this soon.)

Beyond those benefits:

  • Not only are pure functions easier to write, they’re easier to read. Just look at a pure function’s type signature and you’ll get a strong idea of what that function can possibly do.
  • You’ll start to see solving problems as being like algebra, or creating a blueprint as an architect or engineer.
  • As you also saw with the Word Count example, the final solution to the problem is just a matter of combining your pure functions, like algebraic equations.
  • Following all of this logic, testing pure functions is also easier. All you have to do is set up what’s going in the front door, and what you expect to come out the back door. You don’t have to worry about mutable state anywhere else in the application (side doors).

Next

Before we move completely on from the Word Count example, let’s add a real-world scenario to it: your boss comes to you and requests a change.