// TODO: TODO or not TODO?
Programmers have differing opinions on TODO comments (programmers? differing opinions? who would guess?). Some say you should never use them. Others say you can, under the right circumstances, but event then only if you link to an issue in the bug tracker. Others sprinkle them all over the place like parmesan cheese.
I guess I fall in between. Like every other tool, TODOs can be good and be bad. They’re useful in the right circumstances.
The Good
Some stuff is just non-essential or time consuming. Maybe you have a little idea about how to make something better. Maybe you want to change an interface but it will require a bigger refactoring than you’re ready for. Or maybe you can’t think of a better way to solve a problem right now, but it needs to be solved right now, so a hack is the best you can do. TODOs are good for stuff like this, especially if you don’t want to interrupt your flow to do the “right thing” and create a bug in an issue tracker. How does the saying go? Sometimes the flow must… uh… flow.
// TODO: Extract to an interface. <- Usually OK
Another case where I really like TODOs is as a little note to yourself that you need to fix something before committing. This allows you to quickly switch back and forth between different parts of your project without losing track of tasks. You start the frobinator, then realize you need to finish the froobinator first. So you stick a TODO in the frobinator and move to the froobinator. Once you’re done, you can quickly search for all your TODOs and go finish them up.
// TODO: fixme!!! <- Fine for in-progress changes!
Lots of IDEs and editors have a nice shortcut for this. Or you can just use grep. Nice and simple.
The Bad
So when are TODOs bad?
TL;DR: Don’t break stuff. Keep it readable.
Noting potential improvements is good, but your program should still be correct. Don’t commit changes when you’re not sure they work. That’s a recipe for disaster and should never get past code review. TODOs like this are just downright… blecky.
// TODO: Is this right? Check with FlobService team.
As a maintainer, what are you supposed to do with something like this? Especially if the commit history doesn’t give any additional context, and the TODO’s been sitting there for years. Are you going to go hunt down the FlobService team? They probably won’t know what’s going on either. I’ve seen stuff like this production code. Not pretty.
Also, keep it readable. Cryptic or non-specific TODOs are bad TODOs. TODOs that require context that future readers won’t have are bad TODOs.
// TODO: refactor once Deep is done <-- What is this referring to?
On the other hand, a good TODO should make something that would otherwise seem a bit janky easier to understand. It should be self-contained. “Why did Jan do it this way? Oh, I see she wanted to refactor it but didn’t have time. Guess we can do that now.”
Takeaway
So my philosophy: don’t fear the TODO. Noting imperfections and improvements helps others down the road (including yourself). Just don’t use TODO as an excuse to stick something downright wrong or inscrutable in your code base.
And if you feel guilty sticking an ugly TODO in your nice clean code, don’t worry, even Jeff and Sanjay do it and they seem to have done OK.