Placing TODO and ASAPs in code helps ensure you don't leave any loose ends, and if you call another developer onto your feature branch allows them to get a feel for how you're getting on and how complete the code is.
Using a physical notebook distances the workload from the code and hides the fact something is incomplete from others.
A TODO graveyard can be prevented when you review the code - a developer who thinks a feature branch littered with TODO annotations is complete code is either dreaming up future use cases or failing to complete the work assigned.
> Using a physical notebook distances the workload from the code and hides the fact something is incomplete from others.
Exactly. In fact, I use both (except the notebook is an org-mode file, not a dead-tree book). TODOs / FIXMEs in code are for things very context-dependent and connected to code, for which it's important to see them in surrounding context. In more abstract cases, I just log a task in my notebook, to be done later.
Examples of both - code:
//TODO resourcify
(i.e. move to external string resources database later)vs. notebook:
** TODO Refactor the refactor of the SomeClass class.
--Also, often TODO / FIXME comments serve for me as anchors in some larger refactoring processes. I tend to label them specifically for easy grepping (e.g. with unique Unicode chars like ). The point is, refactoring process may take few days, during which I also may need to do some other tasks, so whenever there's a piece of code that needs to be redone but not right now, I tag it for later; I can then use grep/IDE search to check if I didn't miss anything.
//XXX this is bad
//XXXX this is more bad
//XXXXX this is EXTREMELY bad
Allows for easy grepability and a rough, at a glance evaluation of the seriousness of the hack/debtIf you want other developers to see these TODOs in mainline, then they shouldn't exist and instead be in your teams project tracker.
Would you put every task as a TODO in code? No of course not. Its not easy to manage by non-coders, low visibility to anyone not in the file in question, no priority or organizational quality, no way to prune or plan these TODOs, etc etc. If you would wouldn't put every task in a TODO, why put any task?
If you invest heavily in TODOs you just end up with things that should tickets and aren't or vague desires that would never end up as tickets because they're not well thought out anyway.
Often, by the time you officialize a TODO into the ticket pipeline, you could've just fixed it yourself. But the reason you dropped a TODO was because you were already busy with something else more important.
TODOs just sit at a local, unofficial scope in the code. I'm not sure what kind of things you put into TODOs, but if you were to generate a ticket from each TODO in the code I work on, you'd have generated a bunch of low value ticket garbage.
The problem with a rule like "no TODOs allowed in the code" is that TODOs are issues that aren't usually worthy of a ticket, or at least not the time to turn it into one at that exact moment. You'd just be blind to more issues. Not a reason to pat yourself on the back for 'clean code'.
Take the Tensorflow codebase (and Google and Microsoft code, and linux in general). There are currently ~1,028 TODO's in Tensorflow, most of which refer to a particular engineer in the form TODO(<name>):<comment>. This is pragmatism and good judgement in action.
Software engineering is all kinds of shades of grey, competing considerations, trade-offs and balances. It's what makes it interesting.
In other places, I've seen just blanket `// TODO: comment` is pretty bad. There's no accountability and also you don't know when it's obsolete.
(I've got a thing in vim that runs git blame on the current line, and pops up the commit message in the quickfix window).
I find the usefulness/annoying ratio to be very high.
Also, not all tech debt is solved by refactoring.
TODO comments aren't suitable for tracking all technical debt, but they're good for targeted instances.
If you want to fix/change something eventually at some indeterminate time in the future then comment TODOs are a good place for that sort of issue to live.
Instead
1. Quickly experiment with refactoring but stop if it feels wrong. We often underestimate how quickly we can improve the codebase. It's often better to try something quickly than waste time planning to do it.
2. Defer if it's a big refactor or you're on a very tight deadline. Write a reminder in your physical notebook so you don't prematurely pollute your board. If it feels high priority after that and you still haven't had time to do it, then make a chore ticket for it.