xvi Foreword
Continuous improvement seemed more than just a way to make wid-
gets; it felt like a way to live life. It echoed Socrates’s concept of virtue; it
evoked the story of Siddhartha, who sought truth over comfort. These are
ideas about “what should be,” about merit, about substance over rhetoric,
about correctness.
After graduation I rolled into a software development career. Depend-
ing on the company, it was either clown cars and cowboys, or rigid waterfall.
Both were exciting, but no one in either environment was talking about
quality or continuous improvement. When I would bring it up, I would get
sad smiles from grizzled developers. Their eyes said, “Son, don’t you realize
this is war?” The operating systems were crashy, the dev tools were buggy,
and everything was closed source and proprietary. Thucydides said war is
“a rough master that brings most men’s characters to a level with their for-
tune.” Likewise, when the development environment is bad, most developers
will write bad code.
In 2001, a group of conscientious software developers got together
in Snowbird, Utah and signed the Agile Manifesto. About a year later I
discovered it. From my perspective, it seemed like a retelling of Deming,
operations management, and Lean manufacturing. It was the first time
in my career that I’d heard developers discussing quality and continuous
improvement. There was hope!
After five years of test-driven development, pair programming, the
SOLID principles (single responsibility, open/closed, Liskov substitution,
interface segregation, and dependency inversion), and Scrum, my hope had
mostly worn away. I continued to fight my tools, and it remained difficult to
build quality software. Without discipline it was a train wreck. With disci-
pline, process, and diligence, it was a hard slog.
Through pure good luck I encountered Erlang in 2007, and in 2009 I
began working with F#. Functional programming consumed me. I learned
about immutability, recursion, pattern matching, higher-order functions,
referential transparency, code as data, and separation of behavior from
data. As I learned and practiced I began to see the huge cost of OO. So
much of what made my day-to-day coding life miserable was solvable with
Erlang and F#. As I told people about FP, I again received those sad smiles
that asked, “Don’t you know we are at war?” I took it differently this time. I
decided, “OK, sure. Let’s call it war. I’ll be on the side that’s looking at the
root cause of defects. I’ll be on the side that wants to fix the problem at the
source.”
The next stage for Agile must be to fully unravel itself from OO.
Object-oriented programming had boldly promised “to model the
world.” Well, the world is a scary place where bad things happen for no
apparent reason, and in this narrow sense I concede that OO does model
the world. OO as we have it mingles data and behavior; the result is low
cohesion and tight coupling. In OO, there is shared mutable state, which
makes concurrency impossibly difficult. In OO, logic is nondeterministic.
In OO, the result of a function doesn’t simply depend on the arguments
we pass in. The result may vary depending on arguments passed on previ-
ous calls to the function. How about mutations from other functions? How