Who are you coding for?

Engineering Insights

Talin
Machine Words
Published in
4 min readDec 11, 2018

--

When you write code, who are you writing it for?

By this, I don’t mean who is paying you to write the code. Nor am I asking about who your end-users are. What I’m asking is, who is your audience? Who is going to read the text that you have written?

As I write this article, I have a sense of what kind of person is likely to read it. And like any writer who wants to do a good job, I try and shape the text based on my estimate of the reader’s knowledge and interests. I endeavor to “step into the reader’s shoes”, so that I don’t end up accidentally confusing them with too much technical jargon, or bore them by talking to them as if they were an idiot.

The same is true of software engineering. The purpose of a programming language is not merely to communicate instructions to a computer. Programming languages are also a tool for human-to-human communication. They allow us to specify algorithms and data structures in a way that is both mathematically precise and humanly understandable.

But to do this well, you need to have a sense of who is going to read your code. You need to think about which parts the reader is going to intuitively grasp, and which parts are going to require more detailed explanations. This will guide your writing, and help you to author it in a way that maximizes comprehensibility. (I often say that “programming should be considered as a performing art.”)

Who should that hypothetical reader be?

The most obvious choice is one or more of your team members. Another interesting choice is your future self — that is, your code can include reminders of things that you may forget in the passage of time, and want to remind yourself of.

However, I would argue that these are not the best choice for a target audience. Your team members already know many of the things you know, things that you might not bother to explain to them, but which an outsider might not realize. And writing to your future self may be useful if it’s a private project which will never see the light of day, but it also means that you can be as cryptic and obscure as you like — your future self will know what you mean, even if no one else will.

On the other extreme, you probably don’t want to write to a complete stranger, unless you are creating documentation for an open-source project. You need to make some assumptions about the reader’s technical skill level, otherwise you’ll end up writing a giant tutorial on the fundamentals of programming.

Let me make a humble suggestion: the ideal target reader is the person who will replace you.

Imagine that someone comes along three years from now, after you have left the team and gone on to bigger and better things. They are a skilled coder — otherwise, they wouldn’t be stepping in to your former role — but they don’t know all of the things that you knew when you wrote this code.

Try to imagine this person looking at your code, trying to figure out what it does. And not merely what it does, but why it was written that way. Why did you decide to use an insertion sort instead of a quicksort? Why did you pass that argument by value instead of by reference? In many cases the answers will be obvious. But obvious to who?

What I’m asking you to do is to get into the habit of “role-playing” your hypothetical successor, and read your own code from their point of view. And then adjust the way you write and comment that code based on that perspective.

Here’s a pro-tip: one of the best tools for communicating with your successor is through the medium of unit tests. Every test assertion is a statement of intent; it’s a written representation of some assumption or constraint that you had in mind when you wrote the original code. (This is why unit tests shouldn’t use clever coding techniques or be too abstract — you want to be able to read all of the test assertions linearly, as a sequence of logical statements about the code. It’s a document as much as it is a program.)

Think about it: what is the purpose of unit tests? To find bugs in your code. And what is one of the biggest and most dangerous source of bugs? Future engineers who don’t know what they are doing, monkeying around with your code!

In other words, your unit tests aren’t just guarding against bugs from the past: bugs that you accidentally introduced before you wrote the tests. Unit tests also guard against bugs from the future — bugs that could be added by someone who has an incomplete understanding of how the code is supposed to work. Bugs that are completely outside of your control — unless you have good tests.

This means that you not only need to have tests for the things that you think might be broken today, but tests for things that might break in the future, even if you are absolutely, one-hundred-percent certain that they are working now.

Otherwise, that hypothetical future replacement of yours could end up doing a lot of damage.

So, to sum up:

  • Write code as though it will be read by the person who will eventually replace you.
  • Write tests to prevent that person from damaging the code.

See also

--

--

Talin
Machine Words

I’m not a mad scientist. I’m a mad natural philosopher.