Ancient Stoic Wisdom for Writing Better Software

My time at a software company has shown me how much focus there is on the new: new smartphone and laptop models, new revs, new development boards, new languages, and so on. But what about the old? I’m talking really old, like “two millennia before the Unix-Epoch” old.

The Stoic philosophers Zeno of Citium, Epictetus, and Seneca spoke at length about logic, control, and truth–all terms we discuss as programmers, but with very different meanings and applications. Still, Stoic works have lasted for thousands of years. What lessons do the ancient Greeks have for an industry with an obsession for the newest, latest thing?

Epictetus

Via Negativa–The Negative Way

“All philosophy lies in two words, sustain and abstain.” –Epictetus

Via Negativa is a Latin phrase usually associated with Christian theology, but it also describes a tenet of Stoic philosophy. It means removing what is bad or unnecessary in order to focus on what is good. Um, duh.

This seems completely obvious, yet it’s difficult to implement. We often look to fix problems (physical, financial, interpersonal, software, etc.) by positive action: adding more systems, rules, tracking, effort, and to-dos. This adds complication and leads to bugs, burnout, and failed New Year’s resolutions, but it’s familiar to us. The idea of fixing or improving things by taking away is counterintuitive and foreign to us.

What via negativa offers us is simplicity. A real-life example of adding vs. taking way might look like treating a medical condition by adding medication (via positiva), rather than removing stressors, possible allergens, etc. (via negativa). Adding medication might be beneficial, but it also adds a host of potential side effects, as well as hard-to-predict interaction with other medications. Of course, this is a simplified example (and I’m not a doctor), but the idea still holds: Our bias toward positive action and adding things to fix problems can add unforeseen complexity and consequences. Sound familiar?

The idea of via negativa doesn’t mean “do nothing.” Instead, it means striving toward simplicity and asking, “What can I take away?” So, how does this apply to software?

More lines of code mean more bugs. Conversely, “No code is faster than no code,” as posited by software blog Coding Horror and others.

The idea of simplicity crops up all over the place in software. Loose coupling in systems, called “orthogonality” in The Pragmatic Programmer, reduces dependency between different parts of a system. A push for reduced complexity is also seen in ideas like the Single Responsibility Principle and Separation of Concerns. The Don’t Repeat Yourself (or DRY) principle teaches that you should avoid duplication of logic, and that “every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”

Most of us know that simplicity is a good idea: “less is more,” “keep it simple, stupid,” etc. Simple isn’t easy, though, as we have to be cognizant of our tendency toward positive action and more.

Zeno of Citium

Premeditation Malorum–Negative Visualization

(Literally, “premeditation of evils”)

“Begin each day by telling yourself: Today I shall be meeting with interference, ingratitude, insolence, disloyalty, ill-will, and selfishness–all of them due to the offenders’ ignorance of what is good or evil.” –Marcus Aurelius

The Stoics regularly thought, “What’s the worst that could happen?” This ranges from a daily expectation of meeting commonplace difficulty and vice, to contemplating personal catastrophes, even meditating on one’s own death. While this isn’t the kind of attitude that gets you invited to parties, the point is to be prepared, rather than surprised, if–or, let’s be honest–when bad things happen.

“What is quite unlooked for is more crushing in its effect, and unexpectedness adds to the weight of a disaster. The fact that it was unforeseen has never failed to intensify a person’s grief. This is a reason for ensuring that nothing ever takes us by surprise. We should project our thoughts ahead of us at every turn and have in mind every possible eventuality instead of only the usual course of events.” –Seneca, Letters from a Stoic

To the Stoic philosopher Epictetus, such catastrophic events were were “dispreferred indifferent,” meaning that it would be better if they didn’t happen, but if they did, well…it wouldn’t be the end of the world, and it wouldn’t overwhelm one’s strength of character.

This idea is also taught in Cognitive Behavior Therapy as “de-catastrophizing.” Imagining things going wrong allows you to feel these emotions in advance, which takes some of the sting away if (or when) something bad happens. This creates psychological resilience.

Can We Get Back to Software, Please?

Phew, heavy stuff. While this might be a little too “Eeyore” for most of us, especially given the inherent optimism of most developers, preparing for the worst (and hoping for the best) is an attitude that acknowledges the realities of our job. Schedules change, bugs crop up at the most inopportune times, and so on.

To be responsible consultants, we have to continually ask ourselves, “What’s the worst that could happen–and how do I prepare for it?”

Test-driven development is a huge part of our culture at Atomic. We have to test the “happy path” in our code, but we also test a myriad of different ways that things could go wrong. This isn’t an afterthought–we need to imagine these scenarios at the beginning of development and design our systems to support this testing. Forcing yourself to imagine what could go wrong at the outset means that you can write your code in such a way to gracefully handle all (or almost all) that could go wrong.

Likewise, we need a healthy dose of pessimism in our project planning. AO practices a “Fixed-Budget, Scope-Controlled” approach to working with clients. How do project and delivery leads account for hidden risks and things going wrong when estimating project scopes?

One estimation technique uses two scenarios, “highly probable” (HP) and “aggressive but possible” (ABP) to balance between an ABP best-case and more pessimistic HP view. Atomic also strives to have difficult conversations early. Our business relationships are built on trust, so it’s crucial for us to listen to those nagging doubts, and make sure that potential concerns are investigated, discussed with the customer in a helpful and timely way, and mitigated before they turn into crises.

It’s All About Control

This brings us to the central idea of Stoicism: Understand what is in your control, what isn’t, and accept it. But don’t mistake this mindset for complacency.

Accepting that something is outside of your control doesn’t mean giving up. I might not like the weather, but I can’t change it. Denying the cold or rain won’t help me, but putting on some gloves or grabbing an umbrella will.

Of course, this is all easier said than done, and I’ve presented a fairly trivial “Hello World” example of accepting what is outside of our control. These Stoic ideas are difficult to implement, but they offer immense value in our day-to-day lives and in how we write software. So as we’re creating new software and gaining new knowledge, let’s not forget the old.