Functional Programming, Simplified (Introduction)

“So why do I write, torturing myself to put it down? Because in spite of myself I've learned some things.”

Ralph Ellison

The short version of “Why I wrote this book” is that I found that trying to learn functional programming in Scala was really hard, and I want to try to improve that situation.

The longer answer goes like this ...

My programming background

My degree is in aerospace engineering, so the only programming class I took in college was a FORTRAN class I was forced to take. After college I was one of the youngest people at the aerospace company I worked at, and this meant that I’d have to maintain the software applications our group used. As a result, I became interested in programming, and then became interested in (a) “How can I write code faster?”, and (b) “How can I write maintainable code?”

After that I taught myself how to program in C by reading the classic book The C Programming Language by Kernighan and Ritchie, quickly followed by learning Object-Oriented Programming (OOP) with C++ and Java. That was followed by investigating other programming languages, including Perl, PHP, Ruby, Python, and more.

Despite having exposure to all of these languages, I didn’t know anything about Functional Programming (FP) until I came across Google’s Guava project, which includes FP libraries for Java collections. Then, when I learned Scala and came to understand the methods in the Scala collections’ classes, I saw that immutable values and pure functions had some really nice benefits, so I set out to learn more about this thing called Functional Programming.

Trying to learn FP with Scala

As I tried to learn about FP in Scala, I found that there weren’t any FP books or blogs that I liked — certainly nothing that catered to my “I’ve never heard of FP until recently” background. Everything I read was either (a) dry and theoretical, or (b) quickly jumped into topics I couldn’t understand. It seemed like people enjoyed writing words “monad” and “functor” and then watching me break out in a cold sweat.

As I googled “scala fp” like a madman, I found a few useful blog posts here and there about functional programming in Scala — what I’ll call “Scala/FP” in this book — but those were too disconnected. One article covered Topic A, another covered Topic Z, and they were written by different authors with different experiences, so it was hard to find my way from A to Z. Besides being disjointed, they were often incomplete, or maybe they just assumed that I had some piece of knowledge that I didn’t really have.

Another stumbling block is that experienced FP developers use generic types a lot. They also use the word “easy” when describing their code, as though saying “easy” is some sort of Jedi mind trick. For instance, this code — which I’ll break down as you go through this book — was introduced with the text, “it’s very easy to access and modify state”:

def updateHealth(delta: Int): Game[Int] = StateT[IO, GameState, Int] { (s: GameState) =>
    val newHealth = s.player.health + delta
    IO((s.copy(player = s.player.copy(health = newHealth)), newHealth))
}

I don’t know about you, but the first time I saw that code, the word easy is not what came to mind. What came to my mind were things like, “PHP is easy. Using setter methods to modify state is easy. Whatever that is ... that’s not easy.”

Another problem with almost all of the Scala/FP resources is that they don’t discuss functional input/output (I/O), or how to work with user interfaces. In this book I don’t shy away from those topics: I write what I know about both of them.

Learning Haskell to learn FP

In the end, the only way I could learn FP was to buy four Haskell books, take a few weeks off from my regular work, and teach myself Haskell. Because Haskell is a “pure” FP language — and because most experienced Scala/FP developers spoke glowingly about Haskell — I assumed that by learning Haskell I could learn FP.

That turned out to be true. In Haskell the only way you can write code is by using FP concepts, so you can’t bail out and take shortcuts when things get difficult. Because everything in Haskell is immutable, I was forced to learn about topics like recursion that I had avoided for most of my programming life. In the beginning this made things more difficult, but in the end I learned about the benefits of the new approaches I was forced to learn.

Once I understood Haskell, I went back to the Scala resources that I didn’t like before and they suddenly made sense(!). But again, this only happened after I took the time to learn Haskell, a language I didn’t plan on using in my work.

The purpose of this book

Therefore, my reasons for writing this book are:

  • To save you the time of having to try to understand many different, unorganized, inconsistent Scala/FP blog posts
  • To save you the time of “having to learn Haskell to learn FP,” and then having to translate that Haskell knowledge back to Scala
  • To try to make learning Scala/FP as simple as possible