Old gods are terrible to look at when
They weap, all bloated like spoiled fish.
One wonders if they ever understand
That they have caused their grief.
In software development, there is a tendency to take clever short cuts. To use terse variable names; perhaps a single letter.
Or to generalize all to quickly. To think that “Working code wins” is all that matters.
I’d argue that “Sustainable code wins.”
But, we must not be the clever fox prowling along a chained linked in fence; an auburn predator scheming and desperate, eager to ransack and sate their voracity in the coop where golden treasures lie. See The Hobbit’s “Riddles in the Dark” chapter.
Instead, we must look at our solutions as opportunities to share and invite others into conversation and understanding. To share in the problem solving process.
In software you will spend far more time reading code than you ever will typing out code. Those who don’t write the code lose the kinesthetic privilege of writing and thinking through the implementation.
In all things software related, I encourage you to write as though reading code and documentation were all that matters.
What Is in a Name?
at dinner my wife asked: “What do you call the thing that you’ve put your lamp and books on your your side of the bed.” It’s usually a stack of 3 to 5 books.
At first I thought it was a riddle, and I asked as much.
“No riddle, just curious what you call it?” asked my wife.
“A nightstand,” I responded.
“That’s what I call it too, but twice now in a short time frame, I’ve heard people call it their bed side table.”
Interesting, I thought. That is more descriptive and dare I say accessible to everyone. Nightstand is somewhat more opaque; whereas bed side table says where it’s located and it’s function.
That inevitably reminded me of a push I made two years ago at a previous employer.
I wrote a simple pull request to change the variable name from “white-list” to “allow-list.” The original version was “whitelist” but for assistive technology, such as screen readers, separating words helps in announcing the word. A dash (e.g. -) also signifies a word boundary.
Ask someone to explain a “white-list.” In their answer is almost certainly a less opaque phrase you can use.
Then ask “Why is it white?” Odds are good they will invoke the term “black list.” Press further.
When I encountered the word with a fresh perspective, I sought to change the soft-ware variable from “white-list” to “allow-list”:
- The connotations that white is allowed and that black is not allowed is steeped in racism.
- “Allow list” reads as more accessible to those who may be just encountering the term.
I argue that “allow-list” is more immediately descriptive, requires one less mental mapping to arrive at the meaning of the variable. And it breaks the cycle of perpetuating the connotations of white superiority.
In other words, taking the time to name a variable in a descriptive manner can help future readers more quickly acclimate to the context. Could “white-list” refer to a list of CSS Hex color codes for the various shades of white? I’ve never encountered that use of “white-list,” I simply conjured it as a straw dog example.
Aborting Non-viable Premature Optimizations
Another thing is to consider how you’re writing your code.
I cannot emphasize enough how alluring I find optimizations and abstractions. I write in Emacs 📖 and have found myself spending my time hacking on functions that help me better do things in Emacs. This can quickly drift into Yak Shaving.
But I work hard to halt those efforts. This takes some hard-won discipline. That discipline is often in the form of articulating, before I start, what done looks like; or more often what the gradations of done might be.
Then I begin performing iterative tests on what I’m implementing; the more automated the tests the higher my threshold is before I abort.
This can mean accepting some initial copy/paste jobs; or inelegant solutions. When I do that, I try to leave ample breadcrumbs; some code comments that connect the original and the simulacra.
If I’m my best self, I let those changes sit and rest. To not force an abstraction but instead let my active mind rest and let my subconscious join the conversation.
Then with a bit of time and perspective I consider if it’s worth a refactor towards abstraction. Many times the refactor I find reduces duplication of knowledge and improves test-ability.
This is helped by remembering that I am never more aware of my proposed solution than in the moments I’m writing the code. In other words, that’s likely my highest moment of clarity. So I must beware of getting to clever like a fox.
Write as though you will have forgotten all things regarding that code.
To Out Fox the Fox
As programmers, we are experts at seeing problems and concocting solutions. Many of those problems are our own making. A classic example is the great rewrite. Another is chasing new technology in hopes that it will solve your present woes.
When working to solve a problem, it’s important to pause and breath a moment. To listen and ask open-ended questions of those experiencing the problem.
To remember the nature of the problem we’re solving. And not tack on additional problems to try to also concurrently solve.
Strive to understand what done looks like, but also what are the boundaries of the problem space you’re exploring. Our fox brain doesn’t see boundaries so we must help it.
This involves discipline and a refocusing towards empathy. Empathy with ourselves and those that come after us. To help them comprehend what we know. To not place knowledge behind unnecessary jargon that is opaque when something more self-evident is available.
In other words take time to both write documentation and accessible names for the various symbols of your code.
These days when I’m working on a task, I try to first spend a moment writing up what I understand the problem to be. Then I start writing up the responsibilities of the elements of the solution. This is my high-level documentation.
I then spend time writing both code and tests. I frequently rename modules and variables and methods to help gain a better understanding. I look at all of this as my working to better understand the concepts. And renaming is my way of conveying a better understanding to the people involved. People such as my future self, a fellow current maintainer, and those that come after me when I no longer work on the code.
The computer doesn’t know what the word “white-list” means, it maps it to some arbitrary symbol that is meaningful to it. People reading that word also perform a mapping to symbols in their brain; help that mapping process by not be opaque. And provide glossaries to anything that must be “jargon”.
Software developers/engineers work with software; it’s got the word “soft” for a reason. We should look at it as malleable; the words we use as well as the specifics of implementations.
We, as programmers, are here to tell the computer what to do. Let’s continue using our words; understanding that words have power. To name something is, in essence, to say what it is and what it isn’t.