I am not just talking about TODOs, but ALL comments.
Comments do not use the structure of the language or the IDE to help you. They can't be statically analyzed as easily as the existing syntax. At best, there can be some DSL that is implemented in the comments.
I would submit that 99% of your comments can be changed to closures in Javascript.
The problem with this is that you're coming up with an abstraction at a time when you're possibly the least informed about what the abstraction should look like.
I would say that one of the best times to figure out what the API of the abstraction should look like, is when you're implementing the API of functions that apparently rely on it.
You don't need to implement it, but you do need to think about the implementation and API. Otherwise your comments are just wishful thinking, and may not even be implementable. Perhaps the invariants you rely on might be too expensive to compute, for example. When do you think the best time to figure that out is, if not the time when you're writing code that relies on those same invariants?
For example a comment like this:
function something(platform, options) {
if (platform != 'ios') {
throw new Error("Not implemented yet folks!");
}
doingSomethingOnIos();
// todo: implement for android
}
should probably instead be replaced with an Adapter pattern where you implement the ios thing now, and you can add an empty android adapter. Much better to assign tasks to developers and have them already know where to fill in the code, AND have an example in your iOS adapter.
class Something_Ios extends Something implements Something_Interface {
actual tested implementation is here, for others to see
}
class Something_Android extends Something implements Something_Interface {
// TODO: see interface and implement
}
What's better... the first thing or the second thing?
In an ACTUAL PRACTICAL SENSE the second is better.
Now the second one may have a "TODO" but the instructions may just as well be in the issue.