There’s a whole class of math papers that are like, “My boy Erdős proved this big result, and now I’m going to flesh that result out by extending it to an interesting special case.” That’s what this post is. Nothing earth-shattering1, but a special case treatment that’s all too relevant to software engineering.
In technical writing, software engineers strive for clarity — to be quickly understood, unambiguously, by the target audience. Explicitness and precision in names help make writing clearer. Software engineers know this intuitively, even if they’ve never articulated it.
One way to favor explicitness: in designs, it’s almost always best to use active voice. Compare, “The data is inserted into the table” vs “The async writer inserts the data into the table”. The reader now knows what’s writing! Quicker to read, less opportunity for miscommunication.
Active voice, however, won’t save you2. Even with nouns that perform direct actions, authors still reduce clarity by using vague, imprecise names. This is also clear to software engineers who know it’s better to call that variable employeeSSN rather than data.
Precise names, unfortunately, are hard3. Giving a name requires understanding the thing to be named and ordering one’s thoughts. That’s work. It’s easier to say “data”, “list”, or “processor”.
It’s also easier, when writing designs, to say “we”. Going back to our first example, compare, “The data is inserted into the table” with “We insert the data into the table”. Which is clearer?
Right. Neither. In designs, “we” is a placeholder for one of two literal strings:
- “You, dear reader, and I”
- “That thing you probably understand from context”
That’s it! The second option has the exact same pitfalls as passive voice but does a better job of hiding them.
We pull the message from the queue and push it to a channel. We read from that channel, batching messages until they hit the max size we’ve configured before we save them to disk.
Do not be fooled. This is not good writing. It seems like maybe it is! There are nouns doing stuff. But. Applying our string substitution shows how weak this really is:
That thing you probably understand from context pulls the message from the queue and pushes it to a channel. That thing you probably understand from context reads from that channel, batching messages until they hit the max size that you, dear reader, and I have configured before that thing you probably understand from context saves them to disk.
Are these the same things? Does the reader actually understand what the author’s talking about from context? Can the reader confidently draw a diagram from that snippet? Opportunities for miscommunication abound.
Again, precise, explicit names drastically increase the clarity of technical writing and that snippet in particular.
The pub/sub worker pulls the message from the queue and pushes it to a channel. The batcher worker reads from that channel, batching messages until they hit its configured max size. It then passes the batch over a channel to a final worker. That worker calls a remote endpoint which saves the batch to disk.
Takeaway: avoid “we” in designs for all cases where “we” doesn’t refer to humans. There’s always a better word. What part of the system is performing an action? What’s the most precise, explicit name we can give to that system component? Use that name instead.