Programming is all about: Keeping track of the details

The ideas here are those that have I taken away from a presentation given at NET-A-PORTER by Johan Lindstrom

INTRODUCTION

In programming, details matter. The machine does exactly what you say. Whether given software designs from the design team to implement; whether prototyping, or just poking around the code in your Agile team; when programming, the details matter. To design and document a solution upfront so thoroughly that no decision was left to the programmer would be to create something so complex that it would be as difficult as programming, likely to contain more bugs, and likely to take more time. Designs may map out code structure, data structures and interactions, but they are fundamentally confined to the higher levels. The truth is that the people who churn out the software are making a lot of tiny decisions for the company, and all of those decisions add up.

So it’s no surprise that, while you’re typing away into your favourite editor or IDE, you realise you’ve missed something, or there is something else to add. It could be an extra parameter you need to add to your function, another flag in your data structure, or another assertion you need to check for. When you have this moment of realisation, what do you do? Abandon your current train of thought and the task you were working on, or note your realisation and tackle it later?

Sometimes there is no choice, but when there is, it can be beneficial to merely jot the thought down rather than to abandon what you’re doing. Allowing the current task to be interrupted means remembering where you were, what the vision is, and it means forgoing the investment you’ve already made of getting yourself familiar with this specific piece of the code base. Code changes, especially in rarely touched parts of the code base, come with an overhead of re-familiarising yourself with the code every time you return to it. It’s easier to note your realisations for later, than risk losing track of the details involved in your current task.

With that mind, here are some simple techniques to help you keep track of the details:

COMMENTS

Example TODO from Perl's Math/BigInt.pm

Adding code comments containing upper-case TODO, FIXME words provide a convenient, inline reminder of work or changes still to be made. Being inline with the code can allow you to keep the messages very short, as the surrounding code is both relevant and demonstrates the context. Prior to checking in code, you can search diffs for them, or commit them to central repositories for the next person stumbling upon them to fix. They can sit happily in the code for years until the feature gets changed or overhauled, when they can be considered for incrementally better design and implementation.

One of the issues with TODO and FIXME are that they don’t imply ownership. They aren’t directed at anyone, they are considered to be of the least importance, and as a result they can live in the code for long periods of time. At times, they can even serve as a demonstration to code reviewers that the feature or change was considered and knowingly cast off, suggesting to later code reviewers the features were explicitly not worth implementing. If you’re recording things merely as TODO, then it can be difficult to scan the list later to find the ones you wrote yourself and action them appropriately.

An improvement on the idea is to tag things with your own name or identifier (such as JPL).  This way you can filter and review the comments prior to check-in, make an active decision on things that perhaps later become TODOs, or that you are going to solve at the time. For instance, you can tag debug statements inline so you don’t forget to remove them later.

$db->debug(1);        # JPL, enable debugging, remember to remove

exit();               # JPL exit tests early.
#commented_out_code($arg) JPL
warn('#JPL i=$i');    # example of inline user specific todo tag

The technique of tagging things with a unique identifier also helps to spot the exit() you added to the test suite for the sake of speeding up testing; you really didn’t want to check that in!

There are many plug-ins and IDE features that can help you work with your own comments, tags and so forth. One example is the Emacs grep buffer, which allows you to see all the comments, then scroll over the list to see the relevant code parts. The command line tool ‘ack’ is also a good candidate for those not using Emacs: running “ack –all JPL” ensures you find all the ‘JPL’ references in HTML and JavaScript code, fixtures, tests and other non-source code files.

emacs_grep_buffer

Emacs Grep Buffer showing inline TODOs with context

You can also use this approach for larger edits. Say there are 300 different places in the code that make a call to a function, or request a certain object you are thinking of changing. You may not yet be in a place to identify what you are replacing all 300 references to.. so tagging them #JPL, or something else that’s unique to you, enables you to perform something of a code change in two distinct steps. First, you identify the changed locations; later, you make the changes themselves. This allows you to think a little more clearly about what’s required, before committing yourself to making all those changes. It means, should you get halfway through and realise you’ve overlooked something, you can go back and isolate all the occurrences affected by this latest revelation.

ack-grep

Using ack to show the inline comments you left

NOTEPAD

notepad

Text Editor

The next suggestion is to keep a plain document in a text editor (not that you should buy a copy of Windows for its text editor – other featureless text editors are available).

You can use any text editor as a free form todo list, leaving yourself notes that aren’t specific to a part of the code; perhaps a structural change, or something that requires discussion with the team. So, it’s suitable for those tasks that tagging the code doesn’t work for. You can use it like a dumping ground for thoughts and considerations, program snippets lifted from other parts of the code base, bits of SQL, or anything that can help with consistency and readability. You can also use it to remind yourself why you’ve taken certain decisions.

Equally useful is simple pen and paper, which lacks features like copy and paste, but doesn’t take up any desktop real estate, can be faster, and supports simple graphics and diagrams. Personally, I find it more portable, too.

So, I’ve explained that a simple text file is great as a free form tool. It’s yet another tool for keeping track of the details. It’s there, it’s on screen. You dump your thoughts into it, and it remembers things for you, in your own words. It doesn’t distract you, it doesn’t make you think about how to use it, it just allows you to drop a thought and continue you on your current task. That makes it a suitable candidate to help you keep track of changes.

orgmode

Org Mode Todo List plugin for Emacs

 

A step up from a text editor are Outliners. Outliners are simple programs that allow you to represent your notes and ideas in a tree-like structure. They provide grouping of ideas or tasks, possibly helping you to break them down into smaller pieces.

CHECKLISTS

Text files’ and Outliners’ lack of formality and process can make them very easy to ignore. They help you keep track of the details in code, but perhaps not in the software development process. Sometimes, trying to keep track of the details can lead us to forget about other things. We may forget to remove comments, we may forget to write tests, we may forget to verify default values we’re writing into the application.

Checklists, a simple process of listing the things that need to be done, and then doing each thing before moving on to the next, ensure we stay on task. The book ‘The Checklist Manifesto’ contains various examples of the dramatic ways where checklists have helped improve quality of patient care during surgery at hospitals, among other interesting anecdotes.

To adopt this approach for software development, we may develop a checklist like the one below to run before each VCS check-in:

1. grep for 'PRT', replace with TODO or action appropriately
2. eyeball commit diff: ensure it contains no more than you expect
    2a. all warn statements() are appropriate for their error message
    2b. all exceptions thrown are caught
    2c. config variables are sensibly named and contain good default
        values
    2d. no hardcoded magic numbers
    2e. new file contains 'use strict' and 'use warnings'
    2f. do database statements (SQL or DBIx::Class)
        need to be wrapped in transactions?
3. is this one, succinct change?
    3a. can it be broken down further?
    3b. is the commit message succinct?
4. have I tested this in the test suite?
5. does this feature need a feature switch?

The list above contains some ideas, but you may not need such a long list. A three-point checklist may be suitable for your working environment. Maybe you choose only to put on your checklist the same mistakes you make repeatedly.  Maybe you only need it for certain important projects. But being aware of how certain techniques can almost guarantee an improvement to your code quality is worth knowing about.

Hopefully, one of these three approaches will help you “Keep track of the details”.

Leave a Reply