More posts by Nelson Lee
I’ve owned the same screwdriver since I was seven years old. As a kid, I thought it was a pretty useless gift because I wanted G.I. Joe action figures instead. Who knew that after several decades, I would manage to build and repair many things with that same screwdriver. It’s probably the most useful gift I’ve ever received.
However, one weekend, my cousin came by to help me hang a door. When he asked for a drill driver, I promptly handed him my trusty old screwdriver. He looked at me like I was a child. “Don’t you have a drill driver?” he asked. My first thought was, “Drill drivers are for noobs, this screwdriver has gotten me through the past three decades of life. Why would I ever want that?” As I began my rebuttal, he interrupted me, “I can’t believe you don’t have a drill driver! You own a house! How can you not have a drill driver!”
Upon reflection, this reminded me of my early career. School had prepared me for the world by teaching me Turing, Turbo Pascal, C, C++, and Java. My foundation was procedural programming, and I was confident that it was the only skill I needed. How could it not be? It was the world my career and education had provided me.
Learning new tools
Everything changed when my career took me into the healthcare industry. I joined a remote team to build and support a research platform. The codebase had been in development for 12 years. It was running Spring 1 and Java 5. The codebase was continually fighting the team with every feature and bug. The worst part of the project was that it would randomly lose research data.
It didn’t take a genius to understand that something was wrong. Unfortunately, the team did not have the experience or knowledge of good engineering practices. My youthful hubris made me blame my remote collaborators for the poor state of the codebase. I went on to code as defensively as I could and work around their “poor” code. However, after a while, even I wasn’t immune to the bugs and issues. It didn’t take long for me to realize how wrong I was, and that I needed change.
- First-class functions
Immutability seemed counter-intuitive. I was used to writing procedures that would mutate state. When I put together a chair, I always ended with a chair, not a box of chair parts AND a new chair. It was a mental hurdle to avoid changing state and instead return a new state. This seemed inefficient and unnecessary.
However, immutability was the exact property that would solve our data loss problems. After investigation, we found that the researcher would often lose data when they wanted to correct an observation. The steps to reproduce this were:
- Open up a form to correct an observation
- Cancel the correction
When the researcher cancelled the correction, the HTML form would mutate the original data and wipe it out. The action of closing the form would then issue the action to save, and the system would happily save over the existing data. This system had a ton of design issues, immutable data structures would have helped us preserve and replay the data based on the actions. When a system has immutability, it brings a certain amount of comfort and confidence about its state. Even when things go wrong, there’s the safety net to rollback and diagnose why things have changed.
First-class functions was another hurdle to my understanding. With the languages that I had experience with at the time, passing around functions as values seemed foreign. This concept didn’t apply to Java until Guava/Java 8 came out. However, by passing around functions, we found that we could decouple certain actions from each other which resulted in more decomposed and focused code. The result was easily testable and more reusable code.
It’s common to hear opponents say, “Functional programming is unreadable” or “Functional programming is confusing”. These statements are signs of unfamiliarity. Likewise, when one lacks knowledge in home repair, many things can seem magical, unattainable or unknowable. But, by acquiring the appropriate knowledge, new home repair skills can become second nature to the point where life would seem incomplete without them.
The gentle introduction to using immutable data structures and first-class functions has brought me many benefits on a day-to-day basis. Over the past few years, Intelliware has been investing in functional programming. We recently completed study groups on Scala and F# , and are using functional libraries, such as ReactiveX, daily.
By the way, I ended up buying a drill driver, and assembling furniture is now a lot easier. Stay tuned for part 2 of this series where we will be introduced to functional terminology.