Avoiding Hasty Abstractions (AHA programming)
I have seen a number of posts recently expressing confusion and frustration with the AHA (Avoid Hasty Abstractions) programming principle described by Kent C. Dodds. I’ve seen it suggested that AHA is redundant and solving a problem that could be fixed by just sun-setting the dictatorial axioms, arguing that AHA is just another prescriptive doctrine, or that DRY and WET were acronyms selected with purpose while AHA was just pulled out of a hat at random.
It definitely wasn’t random. I should have explained. AHA is not a compromise between DRY and WET. It’s not a dogma at all. It’s an aphorism.
There’s more than one way to over-engineer a system
Getting hung up on when is the right time to abstract or which is the right abstraction is falling back into the arbitrary trap that DRY (Don’t Repeat Yourself) or WET (Write Everything Twice) programming principles put us in. DRY is especially troublesome because while we are inherently pattern-seeking, we are also skeptical beings who are most critical of ourselves and to err is human. Is this really different than that last method I wrote? Is this actually a pattern? Did I already write this?
Why are we so self-critical? To keep ourselves safe by triggering the flight or fight response. In other words, when faced with rules that demand adherence, we panic, over-self-scrutinize, the anxiety escalates, and we end up with a haphazard obscuring of data and implementation in a system with ever increasing entropy. In chaotic environments, we are so susceptible to authoritarianism that we recklessly accept increasingly oppressive structure that provides the illusion of order. We don’t make fewer mistakes with dogmatic principles, we make more and they are more complex. We’re better off with pithy proverbs that allow us the freedom to thoughtfully make mistakes. Mistakes in psychologically safe environments beget order by prompting us to more carefully consider the next solution.
The Aha! moment, or insight, happens when the restructuring of a mental model for a problem triggers unexpected clarity resulting in the solution. Somehow, we know it will work. For insight to happen, we have to develop experience (contemplation, collaboration, Googling the answer, making mistakes, etc) and take breaks to avoid rumination. Rubber ducking and writing tutorials are great methods for disrupting the brain’s structure of a problem space.
When I said we should avoid hasty abstractions, what I meant was that we should try not to abstract impulsively.
Thoughtful abstractions are planned. This can happen early—during the system’s design—or more often, later, when you need it. Careless abstractions are almost always the result of abstracting for unknown scenarios—or when we code a pattern twice and immediately consolidate it into an abstraction before we’ve considered if the two patterns really serve a single shared purpose and will continue to.
Don’t abstract for the sake of abstracting, but don’t do the opposite either! Manage complexity by aiming for simplicity and maintainability with the information you have. Make it work. When it’s obvious and transparent to do so: make it better.
To ask why we bikeshed is to ask why the leaves fall. It is in our nature.
Coding in the spirit of AHA is about thoughtful design that considers the entirety of the system in a holistic way. Everything from psychological safety to algorithm efficiency will affect the integrity of the software we develop.
The universe tends to chaos. It takes hard work to create peace and order. Being mindful with not only computational resources, but our energy—and that of our colleagues—is they key to limiting chaos in the programs we code.