TODO not. Do, or do not.



How often do you encounter #TODO: Fix this ? Too many times? Do you even notice it anymore, or does your sight slides through without noticing? If the answer for this question is positive, then this post is for you! People generally tend to procrastinate the work that is not necessary at the moment - and this is a good way of doing things. Too many time people over-implement a feature that turns out to be unnecessary for anyone – only wasting time and giving no value. Sometimes, while developing, one can spot a place for possible improvement, refactoring or much needed fix. But the worst that can be done here is to place a #TODO only. Why? Read on to find out.

#TODO is present only in the source code. This means that no one besides developers will be aware of it. Not even each developer will know about it unless he works on this particular piece of code. Neither project managers nor the system architects usually access the source code of application and they are almost always oblivious aware of the idea of improvement. As a consequence they will not take it into consideration during their development plans - and as such they will not give programmers time to develop such fix, even when it's much needed. Other developers also won't benefit from this information - they encounter it while doing different task, they don't have to know what author of #TODO had exactly in mind. And it also goes other way around – if you’re assigned to task that is actually mentioned in one of #TODOs you’ll still spent time to examine the flow and eventually find this #TODO – instead of knowing this place right away from task description. Better situation is if we have both #TODO and a task reported somewhere in the system that the company uses. In case of such linked #TODO-task situation we get rid of both problems – the managers know that there is an issue pending, and the developer can always check what this #TODO refers to. But also this approach has its drawbacks - it's much easier to bury a task in the system, and it's way more difficult to coordinate removing actual annotation in the source code.

You may ask if my point is actually valid - as many of IDEs support #TODOs by default and helps us dealing with them? Even frameworks itself have those features (for ex. Rails have rake notes:todo). Well, in theory you’re right, you can usually find all #TODOs in a convenient way. But it comes down to one simple question: Do you even use it? IDEs and frameworks tend to have many features that are barely used and this one seems to be one of them. Developers and project managers tend to have a big scope of duties and unless someone is directly forced to do this, they’re really not likely to do it. Especially when the number of things to check regularly is always increasing as the project grows more complex with time. And last, but not least, what would you do with the results even if you do actually use this feature? Go to the client and tell him “Next two weeks we’ll be making multiple #TODOs, ok"? Not gonna happen. Clients tend to care what they pay money for and don’t want to improve features unless they directly know that it will either benefit them or fix an already existing error. If it’s the first case – then we should have it reported in a system beforehand, if the second – it shouldn’t be a #TODO in a first place.

#TODO tend to stay, very often they last in code long after the author of this comment has already forgotten he worked in the company. They tend to stay even if the idea behind is already gone, and the code changed so much that the intended change is no longer viable. Nobody deletes them, as it's not included in the scope of their task and sometimes they even believe some day this #TODO will fulfil its destiny.

It won't.

So what can we do, when we have an urge to add #TODO to our code?

  • Do it immediately. Job will be done, nothing has to be remembered. This will probably mean that the task will take longer, so this factor should be taken into consideration if we plan to do it that way. But on the other hand you already are in a proper environment and you know exactly what you want to do.

  • Report it in the system. Jira (or any other tool) is a great way for storing such tasks - it won't disappear, managers will be able to see it and if it's important to the project. Assign it to yourself, your superior or your manager - this way it will be remembered. Maybe it will never be done, but this is no longer your responsibility. The good practice here is to describe it as good as possible – event with small implementation details – as it would much help if another developer will cover this in future. In this situation adding a #TODO in the code with the reference to the task is available option

  • Forget it. Sometimes even when you notice a place for improvement, you don't have resources for making them or the effort is too big for the potential gains. Projects are never complete. If somebody tells you that he finished his project, he’s simply lying. Improvement are always possible, updating libraries can always be done. That’s why managers create MVPs – because a developer will always find something to work on. Usually things don’t have to be perfect, they have to be good enough.

As always, there has to be exception to the rules. There are situation where you can safely use #TODO marker. When you’re developing a major task that requires several days or even weeks of work, you may treat #TODO as sticky notes for this task. But only put it where you’re actually planning to develop in following days, not for a hypothetical developer who will work on in unforeseeable future. And remember to check that all #TODOs are gone when you submit your code for review. I think that #TODOs are also acceptable if you develop an application only by yourself and share the positions of developer, manager and even a client. In such case reporting tasks to external services may be a little overkill.

Examples of #TODO

Good example

def index 
   @projects = Project.all
   #TODO Filter the project listed by default. Task: PRO-1  

Bad example

def index 
   @projects = Project.all
   #TODO Filter the project listed by default.  

Very bad example

def index 
   @projects = Project.all
   #TODO Fix that

How does it look like in real life? (state of 01.09.2017)

TODO table (Source: My own research)

As we can see – the well known ruby projects didn’t eliminate the “TODOs” entirely, but the number of them is relatively small (1 TODO on 1-5k LOC). And this is understandable, as sometimes you slightly can bend the rules. The problem is that when you have few TODOs on 100 LOC file. There is almost no chance that you will do them and either you will eventually delete them or they’ll stay there till the bitter end. Because, as always, the temporary solutions are usually staying in the project for a long, long time.