TODO-supported development
Wed, Jun 7, 2017 ❝Why and how to use TODO and FIXME markers to structure your work, enabling you to handle larger tasks and manage your work.❞Contents
When programming, the problem you are solving may quickly become more complicated. Even if the problem itself remains as simple as you expected at first, you may find other aspects that need your attention. Furthermore, it is not unthinkable that there is an occasional interruption of your work. Therefore it is very beneficial if you can adopt a way of working that allows you to reliably defer secondary curiosities for later and mitigate the “damage” done by unexpected and untimely interruptions.
We intend to defer any other distractions (which may very well be important) for later attention in order to keep your focus on a single problem. These deferred points of attention may very well be important. However, by deferring it to a later moment we save ourselves from multiple context switches between two (complex) problems.
The second issue, untimely interruptions, are mitigated by the fact that we are working on “only” one problem. Given the circumstances, it is easier to pick up where you left off if you have only one problem to recollect in memory. Furthermore, if you have only a single problem in mind, it is easier to find exactly at what point you were interrupted. Furthermore, there will be one point to pick up again, instead of having to choose from multiple points and you additionally need to recall which specific problem you were trying to resolve.
Introducing TODO-supported development
So what does it look like?
- Choose a problem or task to work on and start working on that task.
- Whenever you find curiosities, anything that requires your attention really, add a ‘TODO’ comment. Note that we do not want to ban your mind from distracting - that will be tough. Instead we let it get distracted when appropriate but defer in-depth analysis to a later moment.
- Continue working on the original task. Allow yourself to forget (details of) your earlier distraction, as we can always refer to the TODO comment. (Make sure you include sufficient details in the TODO message.)
- After finishing the task, browse through the TODO notes and see what item you want to pick up next. In IDEs this is typically supported with an action list that lists these TODO comments.
This might be one of the newly added TODO remarks, or an existing one, or even something other than the TODO marker.
In most common programming languages the TODO comment may look something like this.
// TODO Consider using a different mechanism here, because this solution does not seem to support this edge case.
TODO “format”
There are a few recommendations for the TODO message format. The recommendations are there to prevent you from diving in too deep. And give you some sense of what level of TODOs could be expected.
- Write TODO message as explanation on what requires investigation. For example, “Consider doing this or that”, “Consider looking into the error cases of this method”, etc. The reason is that this is exactly the entrypoint of a task that requires a context switch.
- Consequently, your TODO might not end up in actual work. The TODO marks an unknown. Further investigate might lead to the conclusion that there is nothing wrong or a use case might not actually be valid and therefore we need not change anything. This is perfectly fine. Further investigation might also lead to other tasks.
- Have different indicators for strictly different categories of tasks. For example, for programming work I use ‘FIXME’ and ‘TODO’. ‘FIXME’ is used for urgent issues that are required for correct operation of your primary task to work correctly, i.e. subtasks or follow-up tasks. ‘TODO’ is used for other things that we need to do. However, they may not be required for your minimal, incomplete implementation. These are like “next steps” in advancement of your implementation.
Rocket science?
Of course this mechanism does not come close to rocket science. That’s not the point. The point is that many people will still try to keep the problems and all other findings in mind. Consequently things will be forgotten. Only some tasks will be recalled at a later time, which may already be too late.
This mechanism is stupidly simple. It is supposed to be stupidly simple. This allows it to be applied in any situation. Furthermore, the mechanism doesn’t require thinking, otherwise we would introduce yet another distraction.
Don’t be put off by many tasks
Depending on the kind of job you are working on, you may accumulate 50+ or even 100+ tasks. Don’t be put off when this happens. You will find out that tasks will become increasingly smaller and simpler. We are definitely making progress as we go through the list and tackle tasks one by one.
Implicit prioritization
Apart from having a TODO list and not having to rely on perfect memory, there is another advantage to being able to list tasks: prioritization. You will notice that, given the list of tasks, you will on occasion read through it and pick tasks that seem most interesting at that moment. This could either be because a task represents a significant issue, or because it is a smaller issue which better fits as an end-of-day activity, or because you don’t feel like taking on something complicated and rather go for a simpler task.
Not ready for the perfect solution
In addition to preventing distraction, we can use these tasks to allow ourselves to go for an sufficient solution and defer the perfect solution. It allows you to solve a problem with a sufficient solution, while marking this solution with a ‘TODO’ for future improvements. No need to feel guilty about your “mediocre” first solution. No risk in “forgetting” about improving your solution. On top of that, we leverage the implicit prioritization discussed in previous section.
Different perspectives
There is an added effect of delaying resolution of (less urgent) tasks. While working on different tasks, you might encounter an existing TODO and read it with a different perspective in mind. Something that seemed puzzling one day, might have a clear explained the next day. By allowing yourself a bit of time, one can consider multiple perspectives on the same task.
Experiences
After doing a number of iterations and seeing the list shrinking significantly, you will notice how thoroughly we were able to process the tasks.
We are able to effectively and efficiently handle an individual task. Effectively, because we let ourselves get distracted only as much as needed to defer a future task. Efficiently, because we allow ourselves to handle a single task at a time and for that reason it is much easier and faster to process. There is little to no overhead included.
On top of that, we can be sure that we do not let issues slip. We can always decide later to drop a TODO comment, but at least we’ve consciously evaluated the task.
Advantages
- Reduced cognitive load.
- Reduced amount of details.
- Improved focus on single problem.
- Significantly reduced overhead, context switches.
- Postpone to make a good decision later, as opposed to rushing to a mediocre solution now. (… or forgetting about it forever.)
- Allow “soaking” of unclear requirements. Test of time will determine if task is still relevant.
- Avoid dealing with multiple levels of abstraction simultaneously. Especially switching between extremes can be taxing.
Requirements
- An environment (both technically and socially) that allows you to make these TODO annotations.
- Optional A tool that is able to list tasks. IDEs almost always do this by default. Alternatively, a fast search mechanism that can search for tasks at request is already sufficient.