What is the story told by your code?
The story in your code gives someone looking at it for the first time a sense of where they are in the codebase. The tests invite them in and give them a sense of who the code was written for and what they can expect from it. The overall structure of the code has a coherence with each piece needing to be where it is. Each line of code serves a purpose. Names have meaning in the context of what the app is doing and each line of code continues the journey of the line before it much like the sentences in a novel.
Tests tell the story
Tests are the entry point into thinking about the intersection of coding and writing. Have you looked at what your test titles look like when you execute them? If you have, do they tell a coherent story? It is easy to smash a phrase or two into a test title, but these are the first, tiny glimpse of your code to the outside world. These tests are also an expression of questions you’ve asked about what you are building. If there weren’t too many questions asked or there aren’t any tests, it is highly likely that there was never a shared understanding about the story the code is supposed to tell.
Test-driven development helps with this because, with your tests, you are creating the outline of what you are about to build. Picture writing a draft novel of 300 pages and then realizing that your main character is flat because they are not conflicted about anything. That’s a lot of writing to toss out because you didn’t do the outlining steps in the beginning.
Plot and structure
Great writing hangs together because there is a polished structure in place. Writers agonize over how conflict is exacerbated by a character’s fatal flaw or how well they have set up their character for the ultimate fall. This same attunement to structure turns into an eye for low coupling and good cohesiveness in code.
An application is not just about one method but about the patterns that emerge through classes and/or components. This shows in the way that each line of your code reads and each piece of code is in place because it needs to be where it is.
Editing as Refactoring
A friend told me that great engineers are not afraid to throw something away even if they have spent a significant amount of time working on it. I’ve frequently heard the same thing whenever I listen to novelists talk about how they edit their work. Experienced novelists won’t just throw away a scene, they will re-write everything from a different point of view or ditch a plot line completely.
Aside from larger edits, there is a joy in tightening down a piece of writing or a piece of code. Although it is important to do the simplest thing first to get something on the page or to get something working, that’s only part of the equation. It is also important to go back through a shitty first draft and excise anything that doesn’t belong, much like a sculptor winnows away until all that remains are the edges that truly tell the story.
Meaningful Brevity
There is a fine line between verbosity and names that are so short they have no meaning. In software engineering, there is a practical reason for brevity. That reason is performance. Extra loops, extra characters and extra method calls stretch out the time required for a browser to render a page just as too many words and writerly flourishes will take the reader out of a story. In a great piece of writing, every word is in place because it serves the purpose of the whole and because it must be there.
Semantics Matter
The semantic names of variables, methods, objects and classes can have a long life and are often repeated throughout a codebase. Not only do they have meaning in the context of where they are being defined but they are creating meaning every time they are reused elsewhere. What will those sentences look like to your reader and how will they live over time? Are the names you are choosing attached to some structure that is likely to be refactored away. If you are choosing names to reflect what a user will see in your app are you using the same language as your teammates who won’t be looking at your code?
It’s about the journey
While it is an accomplishment to hold the book you wrote in your hand or to point to the app you built, this is not the greatest joy of writing or coding. The joy is in the creation. The best days are the days when thought after thought and page after page comes tumbling out. As an engineer, you know what you are building and have broken the problem down into enough small pieces that challenge after challenge lasts a moment, or two moments and then you are writing the next test and building the next object. In pair programming, these are the moments when you’re deep in a two way communication and the code spills into your editor like swift waters rushing in a river and you are floating along.
Writing is a longing to experience this feeling of floating time after time. It’s about setting up your life to maximize the time that you spend in that space of words and thoughts coming together. Just as writers often figure out if they work best in the morning or at night, engineers learn about their own style and how to support it. It might be that your best work happens alone and at odd hours in your own home or it might be that you prefer an office filled with noise of collaboration because that is what comforts you.
Although software engineering has historically been pitched as an activity for people who think in logic symbols instead of words and human emotion, there is value in exploring the strong relationship between great writing and great software engineering. It is worth exploring your own relationship to writing and how that relationship expresses itself in your code. It is often the case that great engineers are also great writers which is proven out in their code. Your code is a novel.