It drives me insane that so many tools/processes treat TODOs as essentially code smells.
Ideally tech debt or code-smell encountered like this would be captured/tracked/described better but often-times this means context switching or engaging in some kind of high-friction activity (like filling out a JIRA ticket) and that just discourages tracking it at all. At least inline TODOs are captured somewhere. And they can be for doing.
Most commits people make are rather bad. Instead of taking us back to the stone age with TODOs, why not encourage better tool usage? Many don't commit often enough and instead tangle together unrelated changes. The cherry on top is when the commit message is just "updating somefile.py" or something similarly unhelpful.
Discovered by the rest of your org? I don't see how a TODO in the code is more visible than a git commit message. In fact, at least it's possible that non-devs may still be able to see the git commit messages in a feed or have read access to repos.
What I take issue with is low quality writing. TODOs are a low quality comment. Commit messages that only tell "what" and not "why" are also low quality. Generally just not having a clean history to look at is bad project management.
A TODO is about something that is not there yet.
Maybe that can be fixed? If I need to git blame the right line, and while ignoring miscellaneous commits like formatting changes, renames, and additional comment additions, then I'm probably not going to find the commit message. Also, if you do all of that just to find a vague commit message, then why bother digging next time?
Best tech-debt tracking I've seen is in the form of TODOs with mandatory links to the issue tracker (thanks to a silly regex pre-commit/pre-submit check) coupled with a team culture of adding such TODOs, as just adding the regex check will just cause lazy and sloppy engineers to not add a TODO at all, especially when facing pressure from other teams.
git log -pM --follow --stat -- path/to/your/file
This will get you all the changes a file has gone through. You can also add --ignore-all-space if that's a problem.
A TODO surfaces details where it wouldn't even occur to me that there's something interesting hidden in the log. Trying to find them feels like smashing the action button everywhere to get a random secret in a game, like secret doors in rtcw or finding stuff with the shovel in zelda.
Usually strong opinions like this come with a more developed workflow.
Yes, that's fine. Developers can also put TODOs in their git commit message.
> Most commits people make are rather bad. Instead of taking us back to the stone age with TODOs, why not encourage better tool usage?
I have a tool which fails if it finds a TODO in a comment without a Jira link on the same line. Since it fails if it finds such things, it's great for CI/CD piplines to block PRs until all of the oddball ends have been tied up and made visible to the product team.
Alas, if we could get the product team to prioritize those TODOs then they can start to be removed from the codebase...
For me it's saying "yeah I know it could be better but I'm not going to break my train of thought over this and context switch. It's not so critical as to break functionality, this would just be nicer."
I really do appreciate TODO hilighting in editors for the odd occasion where I get back to something on a whim and feel like doing a quick fix then. (It's probably not realistically that common though and most will sit there indefinitely)
I often find myself with some time on a plane and cracking open my laptop to dig through to the TODOs that are shown is really cathartic.
If there's a known unhandled edge case there should be conditional logic guarding against it.
If the original author dislikes the idea of a refactor... well too bad it's not their decision anymore, but they should have at least been kind enough to write tests.
Also, a TODO doesn't mean you have not guarded against an edge case. A TODO could be anything that increases the health of the codebase or application. You can guard against an edge case, and then write a TODO on that guard that mentions that you'd like to recover from the edge case, rather than simply guard it.
While I don't necessarily agree with GP, this isn't a refutation. Yes, eliminating code smells entirely is, in typical development environments for sufficiently large projects, entirely unrealistic. That doesn't make them not smells.
> // TODO: If the user triple-clicks this button, the click handler errors because [xyz]
looks more like a comment than a real TODO to me. I agree that comments like those are useful, but shouldn't be a TODO.
A TODO implies a specific type of comment. One that implies a task, points to something that should actually be done (like TODO: This function should return another value with XYZ). And I agree that the proper place for that is a tracker, not buried in the code.
In the example just documents a bug. , there is no actual action.
In my experience, TODOs are often a way to get quick and dirty code approved in a PR. They usually never get done, they're just a way to push the responsibility onto some future developer who "will have more time" (which means it will likely never happen).
// If the user triple-clicks this button, the click handler errors because [xyz]
then it’s less clear at a glance that this behavior is undesirable. Is this a bug, or is it supposed to be this way? “TODO” is a quick marker that (to me) means “here’s something that is not ideal and may be worth keeping in mind if you are working on this code”.
If you or your reviewers know that it’s not OK for the fix to never be implemented, then of course, track it somewhere where it will get done. My experience is that discouraging TODO comments leads to less-documented code, not better code.
Edit: BTW, my specific disagreement is with using "TODO" to mean different things. I'm otherwise completely on board with the kinds of comments you're asking people to write, even if I'd label them differently. When I'm trying to understand new code, much of the effort is in trying to figure out why the author chose the approach they did. Why'd they do this instead of the more usual approach? Did they understand the tradeoffs, or just find things on Stack Overflow or ChatGPT? Did they take this edge case into consideration? Seeing their thinking is vastly more useful than
// Add two numbers
three = one + twoMy favorite TODO was something like class EncryptedSharedPreferences with a "TODO: encrypt this". It was written by someone who left before I joined (I never would have approved it lol). But it made it clear that this code was indeed, unencrypted, instead of having to figure out whether it was encrypted by some other module or worrying that we'd encrypt it twice.
You've already gone to the effort of determining the trigger and the reasons for the error, so you're probably 80% there.
It’s a clear error, but likely unimportant enough to bother addressing.
// TODO: Refactor this by doing X, Y, Z
I'll say // Hmm: This seems brittle. We might want to X, Y, Z this such that W.
My IDE will list all the TODOs and I don't like to clutter that list with stuff that isn't strictly necessary, but it is nice to have some string--"Hmm:", in this case--that I can grep for or recognize as indicating that I thought about this already.- FIXME: this is clearly broken/wrong and highest priority
- XXX: this is “ugly” or assumes wrong things, probably higher than next
- TODO: at some point, implement a whole different approach/category/branch
- NOTE: code comment with a higher importance than just random comment
NOTE: I work a lot with old/unmaintained codebases where “code is truth”, so there is no “jira ticket creation” but amending things as you read.
I rarely use NOTE, but I have on occasion.
And it shows up in some old BSD code: https://www.snellman.net/blog/archive/2017-04-17-xxx-fixme/
But... I think repeated letters are just easier to type than any other string, and since X looks like the classic "marks the spot" logo, it's what people jump to.
https://www.oracle.com/java/technologies/javase/codeconventi...
> Some hackers liken ‘XXX’ to the notional heavy-porn movie rating.
This seems plausible given the older culture ("this is metaphorically dirty, and therefore like porn", insert puerile snickering) and I can recall old jokes about "searching for" these markings. But I think it's also just about it visually standing out - the X character filling the terminal display cell with sharp lines.
It turns out it refers to "moonshine that has been distilled 3 times, reaching very high alcohol content".
- TODO: will be needed before release, mandatory or else turn into another category. Blocks release.
- FUTURE: will be turned in to a TODO eventually, optional, often architectural
- MAYDO: nice to have, very optional
- PERF: do this if more performance is needed
+
some semantic tags related to domain
Opinion: TODOs are NOT code smells, they accrue around the most valuable parts of the codebase.
Documenting it saves the poor dev doing profiling in the future a bit of effort so they can come up with the better solution that you failed to come up with when writing the code.
Often times code has to be written and committed and I don't have the time nor the brains to come up with a novel solution that solves a future performance issue that is not yet and is not expected to ever become a performance issue.
TL;DR: it's just a "TODO profile this".
FIXME: something broken that needs fixing
TODO: potential features/improvements
WARN: noting complex edge cases/weird behaviors
FIXME: I am leaving a note to myself to not get distracted, but this code is not considered finished/mergeable until it's resolved
XXX: this needs fixing soon, but the code will still be functional without it
TODO: this needs revisiting but the code is perfectly useable without it - a lower priority XXX
NOTE: this does something unusual and you need to bear in mind while working on this code
[^1]: the value of doing (or not doing) this is a subject that has already been extensively rehashed in sibling comments
TODO(username,[TICKET-ID,]YYYY-MM-DD): Something left not done, optionally with a (Jira) ticket.
If there are multiple authors or DRIs, replace `username` with `ldap_1+ldap_2+...`
1. An issue tracker, even if it's just a text file for some projects. These are things that need to get done over the long term.
2. TODOs. These are actually bugs or incomplete things. The code is not actually done. Something isn't handled, something isn't right. Big or small, but usually small.
3. XXXs. These are performance enhancements or refactorings. It's XXX because it's obscene that this code looks this way, because it's either ugly, slow, or gross. But the code works and is tested.
Lint the TODO part before merging, then TODO becomes a nice thing you can grep for on your own branch, like a note to yourself.
1. Just file the issue. If it's something you should actually do, you can take 20 seconds to write it down and track it. 2. Just do it. If it seems like too small of a thing to file an issue for, fix it before you commit it. 3. Turn it into a comment. If it's not worth fixing and not worth tracking, but you want to remember it, that's a fine thing for a regular code comment.
Eat your broccoli. Track your todos.
I don’t happen to believe that is true. Pandering to customers makes you part of the problem.
Personally I run myself on a bullet ish journal and I’d probably run my team on Trello given the choice.
For how much longer, though? Been quite a while since Trello was bought by Atlassian; dunno how badly Jira-fied it is by now, but I can only imagine it's going to get more and more so.
// NOTE in the meantime, we added asynchronous loaders everywhere using
// a third party library which makes the page even slower to load, and
// increased the recommended CPU and RAM requirements for both the server
// and the client.
// We also added a noscript tag to tell the users they can't load the page
// without JavaScript so the loaders can load.I find CI integration also makes TODOs more helpful. You can use them to track a genuine TODO in a working branch, but CI will make sure you don't miss them.
You've described a TODO.
If I were to elevate it into a ticket system, besides obviously taking longer than 20 seconds, it would be a distraction, not a help.
It sets a bar for the todo to be at least more complex than creating a ticket. Any less and you can just do what the todo says to do.
The point of a cheap informal method is to as low of a bar as possible so that more information is collected. As for always immediately fixing that’s the same as making everything the top priority, the true priority is lost.
Too many TODO comments and not enough tracked issues, that’s a sign that issue tracking has too much ceremony. Ban the use of TODOs and you lose even that information.
Perhaps a codebase could be watched such that new tracking issues are added and tracked implicitly when checked in by searching for new TODOs in the code. Similarly the tracking issue could be closed when the corresponding TODO is deleted from the code.
The thing about concurrency is that as long as you don’t know about a priority message you can continue to make progress on the task at hand. The moment you are aware of it you have to deal with it or have to explain yourself later. “I didn’t see it” goes a lot farther than, “I did but I was busy.”
My ex would try to check her work email on a Friday evening as we were on our way out the door for a trip out of town. A trip her boss likely knew about. That’s not why she’s my ex but it certainly didn’t help. That email arrived after you already left, lady. That’s your story and we are sticking to it. Don’t go looking for conflict, particularly when doing so affects people other than yourself.
I guess the `TODO` terms has a certain visual flair that makes us immediately understand the class of comment. I guess that would be my best argument for keeping it a `TODO` comment instead of a regular one. But when you see the author arguing that `TODO` comments dont mean you need TO DO anything, it's kind of a smell, isn't it?
I find myself generally agreeing with the article's sentinment but think your option #3 of just making it a non-TODO comment an improvement.
If it’s a WTF about code that is next to the code you worked on, no. Boost the WTF ratio of code that deserves it.
There are plenty of small things that are worth fixing, but not worth as much as the overhead of tracking them.
TODO in code is easy to spot when someone is working on this code, and easy to delete when the code is refactored.
If you put that in the CI, then you can use TODOs either as blockers you wish to fix before merging, or as long term comments to be fixed in a future ticket.
Which is already what you're doing in that system, and what the system is designed for.
Source code is not designed to track and management issues and make sure they get prioritized, so you shouldn't be using your source code to do this.
We add TODOs during development, and then during review we either add a ticket and remove the TODO, or fix the issue as part of the PR and remove the TODO.
Indeed. Who in their right mind would think it is reasonable to track relevant tasks purposely outside of a system designed and used explicitly to get tasks done?
Also, no one prevents a developer from closing a ticket before triaging it. If you fix a TODO, just post a comment and close it. I mean, will your manager complain about effortlessly clearing the backlog? Come on.
No it isn't. The system is designed to get managers to pay for it and it does that very well, it's very ineffective at tracking or triaging issues.
> Source code is not designed to track and management issues and make sure they get prioritized, so you shouldn't be using your source code to do this.
Most things that people build systems for managing outside of the source code repo end up being less effective to manage that way.
I'm sure that's true for enterprise bloatware, but there are dozens of excellent open source and/or low cost issue trackers. Hell, Trello will do about 90% of what you need out of the box if you're operating with 1-3 people.
Perhaps I've been spoiled having worked almost exclusively in organizations where it's completely acceptable to get a message on Slack, or Teams, or email, or whatever, with some bug or issue, and respond with "please create a ticket" and the person... creates a ticket.
Yeah if nobody uses the system, or if you have to expend organizational capital to get them to do it (they view it as doing something for you instead of just doing their job), the system will by definitely be worth less and be less helpful.
The only solution is to be rock-solid in refusing to do anything if there isn't a ticket for it. Your nine-thousand-percent-consistent reply to those emails, text messages, and voice calls needs to be "Yeah, make a ticket about it. I've shown you how, and that's the way we do it. No ticket, no action from me."
If you can't be that "mean" about it, you'll have to be a make-my-own-tickets doormat forever. In that perspective, doesn't feel all that "mean" any more, does it?
Far more intellectually lazy to assume that because people pay for it it does something useful. Have you actually tried working without a ticketing system, not just throwing up your hands as soon as anything went wrong but making a serious attempt?
I wouldn't use git as a basis for it since then management is completely out. Hell, I'm probably out as well since I see git as a necessary evil.
In my experience, these can often be replaced with logger.Error("the todo") or throw new Exception("the todo"), which read about as well as //TODO: the todo, but also can bubble up to people not actually reading the code. Sometimes, though, there's no simple test to trigger that line of code, and it just needs to be a comment.
(I've also seen that backfire and used to punish engineering.)
SonarQube, for instance, will flag TODOs as "Code Smells" and then has some automation capabilities to eventually escalate those to tickets in certain systems if plugins are configured.
I've also seen people do simpler things with GitHub Actions to auto-create GitHub Issues.
Im sorry but that’s exactly the kind of automation that sounds helpful in theory but ends up creating bloat and inefficiency in practice. Like the article says, the second a TODO gets a timer/deadline attached, it stops being a quick, lightweight note and turns into process overhead (note the distinction between something that is urgent and needs fixing now, and something that really is just a TODO).
Maybe a weird way to put it, but it’s like a TODO that used to be lean and trail-ready - able to carry itself for miles over tough terrain with just some snacks and water - suddenly steps on a scale and gets labeled “overweight" and "bloated" and flagged as a problem, and sent into the healthcare system. It loses its agility and becomes a burden.
"But the TODO is a serious problem that does need to get addressed now" Ok then it was never actually a TODO, and thats something to take up with the dev who wrote it. But most TODOs are actually just TODOs - not broken code, but helpful crumbs left by diligent, benevolent devs. And if you start to attack/accuse every TODO as "undone work that needed to be done yesterday" then youll just create a culture where devs are afraid to write them, which is really stupid and will just create even more inefficiency/pitfalls down the road - way more than if you had just accepted TODOs as natural occurrences in codebases
Filing the issue can take as long as writing the TODO message.
Triaging it, backlog management, re-triaging to see if it's still a problem... It's called working on the issue. I mean, do you plan on working on a TODO without knowing if it is still a problem? Come on.
> Issues in an external systems may also be overlooked by developers working on this particular code.
I stumbled upon TODO entries that were over a decade old. TODOs in the code are designed to be overlooked.
The external system was adopted and was purposely designed to help developers track issues, including bugs.
You are also somehow assuming that there is no overhead in committing TODO messages. I mean, you need to post and review a PR to update a TODO message? How nuts is that.
> There are plenty of small things that are worth fixing, but not worth as much as the overhead of tracking them.
If those small things are worth fixing, they are worth filing a ticket.
If something you perceive as an issue is not worth the trouble of tracking, it's also not worth creating a comment to track it.
That way you don't fill your code with a list of TODOs and you'll still be able to track what you want to improve in your codebase.
It might not be the right tool for everyone, but I'd love it.
Better yet (IMO), not removed but replaced by a ticket number or link to the issue.
THANK YOU
// TODO: improve the routing https://jira.com/whatever/TIX-1234
This rule is important because comments can get orphaned. Just leaving a comment is a recipe for a comment nobody knows why it’s there. Just make a ticket or do it now.
I agree that for particularly complex issues you need to file a ticket, explain all the context, maybe give reasons on why it wasn't solved in the original commit. But for forced issues you can easily have the _opposite_ problem to what you're describing. That is: you're left with a bunch of skeleton issues filed only for the sake of shoving it into a TODO comment. Those tickets end up getting auto closed after X time anyways.
Obviously have guidelines, maybe even have a linter warning. But don't implement strict rules. It's a comment.
Nobody says it needs to be one ticket per TODO. For example, I usually maintain a CSS punch list ticket to avoid too much yakshaving when developing functionality. Not only will it be more likely to get scoped and done, but another dev will know exactly where the fixes are needed by grepping for the ticket number.
But the other upside is that if it's really not worth filing a ticket for, why not just do it? I'm curious what scope of work you think is worth tracking in TODOs but not tickets. If it would be a point of work it probably deserves a ticket. If it's less than a point of work, shouldn't you just do it?
> Those tickets end up getting auto closed after X time anyways.
That feels like it reinforces my argument to me. If you can't make time for it when it's a ticket, how would you make time when it's just a comment? At least if the team decides in grooming that the work doesn't really need to be done, it's a group decision and not just me passing the buck.
I've seen this argument in multiple discussion, especially against adding comments or documentation in code because they can become outdated.
But I really strugle to agree : comments/doc ARE part of the code. If you keep outdated comment or documentation in your code without anyone noticing, I'd say you have a pretty big issue with your review process.
Its easy to say that, and probably true, but in a large company with a shared codebase, you don't always have that kind of control. Someone intends to fix something, then the work gets deprioritized or they leave the company or forget.
Maybe you've never seen a comment and realized that the code that goes with it isn't there anymore, but I have. Comments and documentation are important but there's a spectrum of usefulness. On one end it "TODO: Fix this later" and on the other end are comments that are really important with a whole range in between.
The reality is, tickets are the way of making sure work gets scoped and accounted for. If your company measures velocity, having the actual amount of work you do represented in tickets is the way you show what you are actually doing all day. Why wouldn't you want future work to be ticketed? Who does it help?
In my mind, every todo in code is of this type - worth fixing (someday, maybe) but not worth tracking. If it needs to be tracked, put the details in the ticket and just link to the code, don't put a commment in there.
To me, the point of the todo comment is to see it if I am working/touching/utilizing that bit of code. That is the time it should be worked on, not when someone finally gets to a ticket in the ticket tracker.
It's all about the method of action - if the task is something that should be prioritized against other work, put it in a ticket. If it is a task that should only ever be done if I touch this bit of code, then put it in a TODO comment.
Maybe THIS change finally warrants implementing foo, or at least refrain from implementing bar.
Thus introducing the ToDODOs - which is a attempt to hold memory of important tasks facing extinction through cooperate dementia, which those who hold idealistic views of the stakeholders while engineering processes have no living memory of due to job hoping.
Eat your veggies. All veggies matter. Be flexible.
P.S.: This is what I do. My IDE gives a nice list of them.
In each practical project, there is an order of magnitude more things than you could do. One of the crucial job is to prioritize things well, knowing the context.
Regular tasks trackers put things outside of context. Low-priority things might go better in code. That is, you don't need to care about performance of a particular function as it does not matter. But when it starts to matter, and you see "TODO: cache results to speed up", you see an easy win.
TODOs are an excellent place for developers to describe where they'd like to go with a given pile of code if they had the time, and realistically that kind of work isn't suitable for every issue tracker depending on who has access to that issue tracker and who has opinions about what goes in there.
In fact, on my team, all TODOs must have a bug in parentheses immediately afterwards to satisfy the linter. So not only not mutually exclusive, but the opposite.
This format allow for quickly finding the place where the thing needs to be done, while keeping track of the issue in the issue tracker.
I often write the issue tracker ID's in my code to add additional context. It works especially well for bugs which are reproducable in programatic tests. Then I name the test specification after the ticket, so that it's known that this bug doesn't resurface as regression.
TODOs are something less solid than a FIXME and are also just about getting it out of your head so you can devote more mental energy to something else or just relax.
Maybe the idea is not fully formed yet, maybe you are not sure you really want to do it, maybe it is waiting on something else, but it needs to be captured or you will have to keep thinking about it lest you forget.
As soon as I write down a TODO (code or other) that was only in my head, I can relax a little more, because now it's captured for future reference.
TODO
SHOULDDO
COULDDO
The TODOs generally don't make it to main, the others sometimes get picked up eventually.
No, please, do not do this. As notes, those are wonderful things to add. They're the sort of comments I want to see in the code I'm reading! Keep them! But don't label them as TODOs, for the same reasons that you wouldn't use Reminders as your combined actions and notes app.
Edit: In addition to the mental energy, your brain eventually gives up and becomes blind to them. Then you tend not to see them at all, even the actionable ones, unless you step back and dedicate even more mental energy to mindfully going through them one at a time to give them a fair reassessment. This gives me more ADHD-fueled anxiety than I can describe.
This is not a bad thing if they are not for doing. They're there to mark that the code is incomplete but not broken. The actual to do is a FIXME.
Only things that are genuinely actionable should be marked as actions to be done. If it's just something you'd like to clean up, eventually, given infinite free time, label it as a note. Otherwise you're blowing up the amount of information you have to sift through when deciding what work to do.
I tend to use FIXME for things that really do need to be fixed, and will not push code containing a FIXME comment. Grepping for FIXME is useful.
I tend to use TODO for things that I'm thinking may be useful, but aren't necessary (yet). Sometimes it'll be "TODO: Figure out whether..." or "TODO: Validate this by measuring the impact, to see if it'd be better to do something more complicated or simpler." I could rewrite all of these as regular comments -- the latter might be "I have not validated the assumptions here via measurements; something simpler might be good enough." But the TODO is a little more direct. Grepping my code for TODO isn't that useful. (Well, save for the comment block at the top, where I tend to leave actual todo comments, but they're still future tasks not FIXME-style "do this before landing" tasks. And I label them with [ ] checkboxes, not "TODO".)
So we agree: don't use the same tag for both. It sounds like you use TODO for "we need to change this" and I use FIXME for that. I suspect we all have a broad range of labels: TODO, FIXME, NOTE, plain comments, comments linked to bugs, etc. When reviewing teammates' code, I check whether their TODO comments should have a bug link, should not say "TODO", should be removed entirely, or whatever.
// TODO: Write the second half of this file so next week's launch won't explode
then sure, you should probably track that somewhere.
and // TODO: If the user triple-clicks this button, the click handler errors because [xyz]
So my comment is also in that context of using the same tag for things of wildly different importance and urgency. And that would drive me to drink.Definitely come up with a local convention for which tags mean what, and pick whatever resonates with your team. TODO in your org can mean something different from mine, and that's perfectly fine. Just please, please use different tags for different things, as you're recommending.
Ah, ok. That's fair. I agree that the example comments ought to be considered different categories. That first one is a TODO that is for doing.
> And that would drive me to drink.
Is that a bad thing? It depends on what you're drinking.
Soon, though.
//this is an info level comment
//TODO: change the downstream code so it's less brittle after we get to prod(WARN)
//TODO: don't hard code this variable, had to get prod up and running due to leap year
In my experience TODO are most commonly placed by either the guy doing a greenfield project, the code maintainer, or the guy getting production out of the ditch at 2am on a Saturday. I don't think I've ever seen a junior dev write one. My code has a few TODO sprinkled in but they're fairly rare, and call out where I had to make a decision due to constraints, and inform which direction I intended to take.
In some other cases, they don't have to be done now. They're bottom priority. A hardcoded color that won't work with dark mode, but we have no plans to use dark mode, etc.
Anyways, I'd be happy with a structure like
- "NIT" that acts more like notes for correct implementations used for highlighting potentially better structures or optimization to consider farther down the line
- TODO for issues that can or will become issues later on, but are otherwise functional for prototyping purposes. I don't think every TODO needs to be corrected, but you should have a refactoring day every period where you address most of these TODOS.
- FIXME for critical or showstopper level issues, but you need to clock out for the day. There shouldn't be any FIXME in a stable branch of code. Arguably a FIXME shouldn't persist for more than a few commits.
So the label is kind of useful: for flushing out the people who need it explained -- now you know sho's sloppy enough to be worth being wary about.
> Most users won’t end up triple-clicking that button.
Absolutely they will. If they're on slow enough network speeds, they might get frustrated and start tapping / clicking away. I grew up on Dialup internet, I remember the struggle.
In my opinion, the author describes more of a NOTE, such as, "Currently, we support X because of the requirements in TICKET-X. If you want to support X and Y..." or "This was done like this because of X. The better solution is Y and it make sense to do the better solution when ...". I like the idea of helping my future self quickly understand why something was done in a specific way and how I can refactor it now. Also this indicates that how ever added the NOTE, is a good software engineer, that does not implement features or functionality that is not needed yet.
Of course there is: Put the ticket number (or URL) in a comment.
If usage takes off by 100x, someday somebody will be tasked with clearing up errors in Sentry (or whatever) so bugs and regressions are easier to spot, and this comment will save them hours of debugging.
However, I think using TODO to flag it is a poor choice. Good luck explaining to your teammates, "We use TODO to communicate that we aren't going to do something." I doubt you're going to get consistent adherence to such a counterintuitive convention. Instead, I would prefix the comment with "KNOWN ISSUE."
PS Hi Sophie!
For example, this TODO:
//todo: factor this out in case X
…is a NOTE, albeit a gratuitous one.Because if X ever happens, the note won’t matter anyway, since you will have had to grok all the related code to refactor. You will see this note while you’re refactoring the surrounding code and smirk, “yep, that’s right”, or “no, it doesn’t really fall out that way.” Either way, most TODOs/NOTEs like this just get in the way.
It's a "to do" but on a long (perhaps indefinite) timeframe.
How about by writing a comment containing the words "would be better if"?
Personally, I tag my comments in one of two ways:
1. // TODO: <task> (if multiple things, I do a multiline comment with Markdown-style checkboxes next to each item in the list).
2. // NOTE: <explainer>
The former is what you'd expect (I routinely search for these to make sure I'm not missing minutiae) and the latter is for code that can't be refactored to make it clear and requires some explanation.
Doing this consistently has really saved my bacon over the years (both in terms of keeping track of tasks and remembering why I had to use that ridiculous chunk of code to get something to work).
TODO, TODO, TODO TODO TODO TODO TODOOOOO
...No?Ok fine, how do you track completed TODOs?
With TADAs!
Ok fine, I'll show myself out. // TODO: Find better materialSounds to me like this should just be a regular comment. Don't add "TODO" if you're not actually going TO DO it.
it's a game changer while solo or on a team. and I’m sure it's reproducible outside of vscode (it's just highlighting depending on the todo token used).
been using it and introducing it to teams for years. it's even more helpful now with AI.
>> // TODO: If the user triple-clicks this button, the click handler errors because [xyz]
That could be a simple comment, but if its a TODO it should be ´TODO(bug/<id>): Fix triple-click error in this button´.
If you really want to tag a normal comment, what about // NOTE?
An example from my codebase is that I implemented a daily scheduled job that may display inconsistent results during short time per day it is running. Realistically fixing this will never be worth my time, this is a transit app and it is scheduled to do this at night when the buses aren't running and it will only be inconsistent if they change the schedule after already publishing it for a given day which happens pretty much never. It is also a personal project with no issue tracking.
Eventually I will rewrite this loader logic to support multiple transit systems so it is good to have my notes of how I would do it better next time. Also, if this does result strange schedule behavior I would immediately go to this file and see my explanation of the flaws with my approach. Maybe I shouldn't call this a TODO but it seems like a good fit.
My codebases tend to use TODO exactly as described here. A TODO is really just a comment documenting the implementation -- specifically, documenting something that is missing, but could be useful. It doesn't mean it actually needs to be done.
IMO it doesn't make sense to use comments in the codebase itself as an actual task list, because priorities are constantly changing. Things that seemed important when you wrote the code may turn out not to be, and things that you didn't think of when writing turn out to be needed. Are you constantly submitting PRs just to update the TODO comments to reflect current thinking? I mean, sure, I guess you could do that, but I think it makes more sense to maintain that list in a bug tracker or even just a text document that can be updated with less overhead.
It's very local, this code should change but it might not be possible during the timeframe I've been given.
For future reader it might give hint what to change or what is wrong here.
// TODO: If the user triple-clicks this button, the click handler errors because [xyz]
This is documenting what currently happens. It's not TODO, and that word shouldn't be in the comment.
When I left a job after many years, my collegues printed a listing of all my // TODO(pht) .
It was big and full of things that never got "TODONE".
TODO? or ?TODO: Documenting funky code that the developer can't triage at the moment without losing flow state but is "off".
Instead of a separate MAYBE any action should have an indicator of confidence level.
We are marking the developers intuition about something they have run into, human intuition is both important and fuzzy, we should mark it as such.
The more ? the fuzzier it gets.
Humans have a bunch of symbols in their brains, we may disagree about the symbols usage but if a developer has a small thought about a codebase let them get it out quickly and with clarity.
The real problem is that unified tooling for plaintext editing and zoomed out team project management don't have a good interface that let's people notate with the level of friction commiserate to the importance of the notation.
// NB: If the user triple-clicks this button, the click handler errors because [xyz]
Edit: "Nota bene" apparently: https://en.wikipedia.org/wiki/Nota_bene
In my org, TODO comments trigger the linter, so they usually have to be addressed, downgraded to a regular comment, or turned into a ticket. They're a nice way for me to mark places I need to remember to come back to before I put something up for review.
I sympathize heavily with the viewpoint that pushing these things into ticketing systems means they're less likely to get done. I think it's nearly impossible to lobby for TODO: comments to get done against a never ending stream of ultra important high business value work. Leaving these concerns inside of the codebase itself is one way that programmers can take back control when technical concerns and code quality are dismissed or deprioritized constantly.
However, once I read them all of them, were exactly this: very rare edge cases, minor optimizations, and notes about future optimizations possible optimizations.
I pretty much immediately adopted this style of todos.
I also agree with users that sometimes these should just be comments. Really depends on your environment and since I work on a team of 2 who maintain my portion of the codebase I stick with using TODOs in this way (seomtimes).
// PBD: Possibly be done...?
// NBD: Not being done!
And, Idunno, perhaps some more.When I'm then doing my final commit I'll do a search and check them off.. Theyre incredibly useful. I use pen and paper too but they go missing
// TODO: optimize something, refactor, blah ... // TO_F_DO: this thing is gonna blow up, can't fix it now but do it ASAP
TODO - when I have nothing to do I browse those, pick the on I like and do it.
TO_F_DO - if I find more than 1 in my code I am suicidal
Step one is: learn English.
I would argue TODO means “intent to implement”, and they should be regularly converted into either tasks, documentation or just standard comments without a special keyword.
That's probably the main point of code comments in general: to explain to the future reader or maintener (who may be your future self) why things are the way they are.
Todos IMO should be limited to branches but not merged to trunk.
Why is it a TODO, and not a NOTE or something?
TODO is something you need to do, not just a remark about the code
- won't have sufficient positive impact on the bug/feature you are working on
- you don't have time to address at that point in time
- are significant enough to require pay down later
How to address them in terms of tooling and process is a way bigger question
Also, the first and most important place for putting TODO's is the issue tracking system so I think in most cases they do not have to be in the code. I might allow them occasionally if they refer an issue in the issue tracking system. Another use of TODO comments that is not necessarily bad is if you yourself or someone else is supposed to resolve all of them before the relevant code is merged into mainline.
Something that needs to be fixed in your local changes before committing, lest something break terribly? Put it in code in such a way that your CI system will reject integration. That can be a // TODO or // DO_NOT_COMMIT comment that can be recognized and rejected by your git pre-commit hooks. Perforce lets you stage and describe changelists before committing them, and you can make hooks that will reject TODOs in those descriptions as well. In a pinch, #ifdefs to check for CI and a static_assert(false, ...); might be another option. One of my more common uses of this pattern is when extending or refactoring a platform abstraction layer - it tends to be easier to get it working on one platform first, and forgetting to test it on a second platform can be very easy. Switching contexts to an external issue tracker for things that nobody but yourself will ever read isn't adding value - keeping it in code where you can build safeguards that will literally prevent you from doing the wrong thing by accident will.
Internal refactoring or performance improvement suggestions? Those often go in the non-blocking non-tracker // TODO bucket for me. They can safely rot away unnoticed for 10 years without causing problems as issue trackers come and go, then suddenly become relevant as new needs cause new development, and as new development causes old problems to become new again. Producers aren't going to have useful input on if the refactoring or performance suggestions are relevant - the developer poking around the existing code isn't doing what they need it to do anymore will.
Or
// NOTE:
Work for this and are just as searchable.
There are times where you can’t rewrite or refactor something or have Toni’s ran API with non-obvious behavior. Plus NOTE is shorter than HERE BE DRAGONS
this is why there is a difference between TODO and XXX
XXX is old-school, "popularized in early Unix-related projects like the Berkeley Software Distribution (BSD)", and acted both as TODO and warning.
amazingly, now, we can simply have both!
- TODO is literally "do this before merging, or, make an issue"
- XXX is "gah this is a bug and i can't fix it right now. i am putting the XXX so it stands out from non-bug comments"
it_citizen•6mo ago
happytoexplain•6mo ago
Edit: And if you put them in a tracker, they'd be distracting and confusing for team members less intimately familiar with the codebase, e.g. a PO. You could also choose a word other than "TODO", as long as it won't produce a ton of false positives in a search.
dorian-graph•6mo ago
marcosdumay•6mo ago
jraph•6mo ago
Even better: for understanding why some code does this surprising or seemingly complicated thing it's doing