Trusting code

The school run

When we start a new school year, my wife and I have new routines for getting our kids to and from school. And those early weeks are filled with text messages going back and forth like “You’re collecting kid 1 today at 3pm, right?”, or “You know kid 2 has after-school club today, right?”

It takes time for the trust to build that the other person is checking the calendar, has set the right reminders, and knows the routine.

After a few weeks, these messages stop (until there is an exception to the routine!).

You have a relationship with your code!

You kinda have a relationship with code from your projects. You probably have feelings about it. It can delight you, and it can frustrate you. Like with a friendship or romantic relationship, you’ll get the most out of it if you invest in it, tend it, nurture it. If you neglect it it will slap you in the face the next time you demand something of it.

Trust is also something you can have – or not have – in a code base.

As I’ve been thinking about code style, I’ve also been thinking about how it’s important to build up trust in a code base.

You keep using that word. I do not think it means what you think it means.

Sometimes I have a project that I’ve been looking at where I don’t trust it.

I maybe don’t trust it because I know it’s poorly typed, or not typed at all, and so I know edge cases can creep in.

I maybe don’t trust it because it has no tests.

Perhaps it’s so complex and poorly documented that I’m not convinced the author know what the code did, let alone this newcomer to it.

Or maybe it just seems muddled and badly structured.

In any case, I might be reading some code like this and come across a function call like:

validateEmailParameter();

And a function definition like:

// Validate the email address.
function validateEmailParameter()
{
   ...
}

Without further information or context, I might have a lot of questions about what this does.

  • Where is the parameter that’s being validated? This might be evident from the context, such as inside an HTTP request handler. But it might not.
  • What is a valid email in this case? Have they implemented this robustly?
  • Does it only accept a string? Does it handle other types or null? Does it handle an empty string?
  • What might this return? Does it return? Could it return an error code or exception?

In an untrustworthy codebase, I won’t make assumptions about a function like this. I will have to open it up, read through the code, and figure out what it does. This takes time, and for more complex situations this can really slow me down.

BUT, if I trust the codebase, then the function definition will probably be something like this:

/**
 * Tests if the "email" parameter passed in the URL query string is present and is a
 * valid address. If it's not then a 400 HTTP status code will be returned and the
 * application will exit.
 *
 * If the address is present and valid, true is returned.
 * 
 * @return boolean
 */
function validateEmailParameter()
{
    ...
}

This is a contrived, awkward and simple case. But in a case like this I’m much more likely to believe the function’s description and not even read the code to see what it does.

Earning my trust

However, this trust isn’t a one-off thing. My trust in a code base is earned over time through repeated exposure to good practice, good documentation, attention to detail, and other factors.

But once it has my trust, it’s so much easier to work with without having to go spelunking. I can work with it faster because the mental overhead of reading it is so much lower.

This post sits as a sidebar to my series on readable code. They go hand in hand.

The readable code tips work best when a code base is trusted. But they are also one of the ways in which you can build trust in your code.

So think about your work. Do you trust the code in your projects? If not why not? And what can you do to make your code more trustworthy?