Hacker News new | past | comments | ask | show | jobs | submit login
Using TODO For Everything (goldin.io)
235 points by GoldinGuy on May 2, 2022 | hide | past | favorite | 174 comments



I pretty strongly disagree with this. The advantage of using TODO for everything, is that it's easily searchable, and you don't have to try to guess/remember, which labels are used for your comments. If your task is more nuanced than a simple TODO, you can explain in the description after the keyword. The purpose of the keyword is to make it easy to find and take action on in the future, and moving away from using a single keyword makes it easier to miss a comment and harder to take action.


Full agree. They also write

> the value of using a broader selection of terms is that you (and therefore all the other programmers you’re collaborating with), are able to be more descriptive about what it is precisely that you need “to do.”

But that's what the space after `TODO:` is for. To say what it is you need to do later.

The less complexity you add, the less you have to maintain. This mainly applies to things of a certain smaller scale, but I find I encounter `TODO` in my code when I am in a certain scope or just have some free time to refactor, fix things, etc., neither of which require anything beyond a searchable string, as you mentioned.

This reminds me of any note taking app that uses #tags. You start in earnest and tag things; you end up with twelve different tags for #cooking, #baking, #food, #recipes, etc. because you forgot which one was which when organizing; it falls into disarray; you are left with unusable cruft, so you end up just searching for "bread" in the search bar, anyway.


That exact problem you mention about tag saturation is why I switched entirely to a zettel method where notes are only organized by what they link to or from. Tag structures also just aren’t that great for later recall.


That's kinda what made google win when it stomped alta vista into dust, right?


No, it was infinite free money that made Google the winner.


And what about notes that doesn't have/need any link?


They go into the slip box to be searched by raw text when needed.

Edit: Really, in a zettel flow, you’re supposed to capture notes as fleeting thoughts that are processed and synthesized later into long form writing.

Each note should initially have few links (if any) until you’ve ruminated and expanded on that note in your own words. These are usually called literature notes in zettel workflows.


That's a totally fair assessment - I can certainly relate with tags in note-taking apps


I utilize a mixed methodology: TODO-X, where X is a subcategory describing what kind of TODO it is. For example:

TODO-BUG TODO-OPTIMIZE TODO-FEATURE


I just do something like:

// TODO: Optimize this function

// TODO: Finish implementing this feature

I also label comments with BUG, NOTE and HACK, but not for unfinished items on a todo list.


I as going to say the same (except more "TODO FIXME"; either works). It's trivial to just do both, making it generically and specifically findable.


This is great.

Which other subcategories do you use?

Todo-incomplete Todo-refactor

Some others I imagine?


At least in Visual Studio and I assume other ides you can get nice solutionwide lists of other tags, and even add your own. But I’d agree, easiest thing that works in most cases is just TODO: I’ll sometimes add !!! To really important todos.


They say there are two hard things in computer science and 'naming things' is one of them.

Every benefit you listed is legit, yet not even the sum of them can compensate for the loss of fidelity and lack of human scalability which results from using 'TODO' for everything. Anyone competent enough to edit code can handle holding 'seven plus or minus two' types of comment tags in their head. Those who can't (or, more often, who can't be bothered to) aren't suffering from impostor syndrome. They might actually simply be impostors.


grep TODO * -r is my issue tracker


IMO, I only use three tags: DREAM, FIXME, and HACKS. The whole point is to write less code and better establish when to revisit things.

- DREAM tags let me focus on getting things shipped and avoid over optimizing/generalizing things that won't provide immediate value. When working in a professional context, they are always accompanied by a ticket. This adds a nice binding for whoever comes next to pick up the task.

- FIXME is also used to help maintain focus, but with the rule that no code ever gets merged with this tag still in place. For personal projects my branches tend to be quite large, so I'm comfortable accumulating some small number of these.

- HACKS calls out unintuitive behavior: breaks in abstraction layers, worst-practices that have better implementations than best-practices, or anything that smells "clever".

Everything else is just comments that future me/team can look back on and say "he must have been drunk when he wrote this, but thanks to these comments I can clearly understand the context and at least what was intended."


Another reason for a system like yours is TODO is just another backlog but one that no one tracks and grows stale.

I much prefer either

- TODOs are resolved before merge (your FIXME)

- TODOs are moved (not copied) to the team backlog (maintaining in both places just gets them out of sync)

- TODOs are converted to documentation explaining the approach (e.g. HACKs)


> that no one tracks and grows stale

On the contrary; since they are right next to the thing that needs work you always encounter them Just In Time. And you can just delete them really easily if you decide they're truly stale. This may not lend itself to planning or management visibility, but for a small private project I prefer them to the overhead of separate tracking.


> for a small private project I prefer them to the overhead of separate tracking.

For a small private project there's no organisation which doesn't work.


Actually, I'm increasingly finding that because my work on these types of projects happens sporadically, it's easier for me to get stuck not remembering what I did or need to do.

I don't have anything resembling an issue tracker, but I've begun collecting brain dump style notes in either a gist or the Apple notes app.


I'm the same. I fully expect all my side projects to be interrupted / paused for months at a time. This for me this does include a ticketing system, version tracking, rationale documents, wiki etc aren't optional for me.

Some of my side projects have more process around them than my work projects because the side projects will definitely get shelved at some point and resumed much later. Future me is always happier when the process was applied.


> since they are right next to the thing that needs work you always encounter them

That means they become scenery, not something in the foreground. They are lost.


4th option:

- Create ticket in team backlog and add ticket number to TODO comment (and have CI pipeline check that ticket number is valid)


You need to check both that its valid and that its still open. Many times I've seen TODOs with issues in code where the issue was closed. Since nothing gates the Issues being closed, you've now broken CI by closing them.

Say you do get past that hurdle, you've added friction to the process of managing the backlog because the code now needs to be updated when Issues are rejected.

The sad part? With almost 10 years on a 20-30 year old code base with many millions of lines of code that are littered with TODOs, I don't think the presence of a TODO was ever helpful when we decided to actually fix an issue.


> The sad part? With almost 10 years on a 20-30 year old code base with many millions of lines of code that are littered with TODOs, I don't think the presence of a TODO was ever helpful when we decided to actually fix an issue.

Makes perfect sense. TODOs are comment, meaning they're as reliable as comments, meaning they often aren't (and the more time passes and code churns around them the less they are).


Totally agree. I've found that adding a timeline to _remove_ TODOs/DREAMS (whatever the team choice is) from code as a CI check is very applicable -- what you thought might be good at some point in the past may (and likely is) not applicable later down the road!

Clean the code, comment actualities later, etc. -- it helps with knowledge share to find ways to make you attend to cleaning things up.


I've done this too (commenting with the ticket # - well, link to ticket), and it's worked quite well for me/us. It's fairly easy to follow the link & check on it, and it can also serve as a tombstone for why a particular issue isn't being addressed.


I've been tempted to put issues in the repo, which would solve this problem (and create others).


Something I've built for myself a couple times is the ability to decorate a test with a ticket number so that the test is expected to pass if an environment variable (usually TICKET) is set to that number, and otherwise is expected to fail.

I also sometimes include a stricter version that includes a test for the current behavior, on the theory that someone changing the current behavior might be in a good position to fix the ticket.


> Something I've built for myself a couple times is the ability to decorate a test with a ticket number so that the test is expected to pass if an environment variable (usually TICKET) is set to that number, and otherwise is expected to fail.

I don't understand that use case.

Do you mean that if you set the envvar, the test now becomes "normal" because the assumption is you're trying to fix the ticket, and thus make the test pass?

I guess that makes sense if your workflow is to "clock in" on tickets, to which you can hook env updates?


You have it right, although "clock in" sounds a little formal; I'd probably just say "start work".


I may switch to using FIXME for my personal mid development comments. But I do like having the TODOs maintained with a ticket number in the backlog. Such that you can find the relevant code easily, but there is a ticket and its not forgotten. Especially when it relates to weird behavior in a specific section of code. It also lets people know that that section still needs work when they see it while working in the codebase. Maintain the meat of it in the actual ticket for sure. But `TODO: ABC-123 - brief description` shouldn't really get out of sync. At least hasn't so far for projects I have worked on.


This is absolutely my second system, and one often preferred over my ... um... preferred system :D. In other words, I have my personal bias, but this approach is far easier to scale with a team over time.

I still tend to keep the "HACKS" thing though, simply because they localize the documentation right where you need to be aware of it.


For hacks, I use REVIEW to declare that this code is the way it is but an aspiring soul is welcome to submit a PR that replaces this code with a working version of the "right way to do it". It shifts the burden from the developer who made it work to the developer who would prefer it work some other way which allows the project to make progress.


What about a hack, that needs to be fixed, but in reality fixing it is only a dream?


That's the code in production.


I like the idea of DREAM. I find that there are lots of things I would like to improve, but not worth it at this time. Or even maybe ever. But it doesn't feel 'standard' either. While I am sure a team could set up custom highlights and the like, but it has seemed better to just use the standard ones that get picked up by most tools.

Is the use of HACKS just to highlight the importance of a comment? I tend to just stick those in a regular comment. Or if extra important NOTE at the beginning. For instance I refactored code the other day forgetting why it was the way it was, it didn't work, and then made a NOTE for it so I don't do it again.


The point is to avoid having to search these out. IMO you're playing a losing game if you find yourself doing this.

For "DREAM" there is a ticket for proper tracking. For FIXME, code review prior to merge is sufficient. For HACKS, you really only need to care when you happen to be working in that space.

And yes, HACKS is to highlight the importance of a comment. It also signals an intentional deviation and an opportunity for someone to offer a suggestion on how to improve things.


I've had good success using a system with two levels of severity:

- // STOPSHIP: the presence of this string anywhere in the codebase causes a production build to fail.

- // TODO: for everything else.


My one tweak would be that in projects in development, the hard rules are less applicable. Sometimes I've found hard-coding some things (e.g. FIXME items) are to make it into production when developing a prototype and testing (< 1.0.0).

Once you're reaching 1.0.0, you know these can no longer be sliding through, and you can support all of this in CI.


What about "// TODO !", "// TODO !!", and "// TODO !!!". Where the number of !s indicates the urgency - the more the urgent.


I love this. I'm going to try using this going forward.

Edit: I just added this into my editor but it's not highlighted by default. I wonder if there's a way to highlight it.


TODO: Add highlighting by default.

There, fixed it.


Jetbrains supports it, and I'd bet there's an extension for it in VS Code



Well then that depends on the editor, but surely it’s possible in whatever you’re using.


Ok but my tooling defaults recognize TODO and I have many pending deaths on other hills of higher precedence.


Exactly. Plus if I want to find things to fix in my code, searching for TODO is much easier than searching for each of a dozen or so other strings.


As mentioned in the post, if you are looking for things to fix, you should be looking in an issue tracker. I was trained to put the issue number next to the TODO. Furthermore, we tag the issues so that we can easily identify simpler issues that can help spin up new team members.


I think todos and tickets have separate use cases. I use todos as short term work trackers. I put them in as I'm writing new code, then usually complete them before I check in, certainly before I merge my branch. Sometimes they slip past me and get into the main repo, but that's a better outcome than just forgetting about it entirely and I don't have to pay the cost of writing up and managing tickets for every loose end. I open tickets for things which will need to be done as a separate work item at a later time. I don't tend to put in a todo with the ticket number because usually something on that scale often doesn't have a specific place where it belongs.


I pepper my code with FIXMEs while it's under development and I'm working on just getting the happy paths to run. Then I go back and fill in error handling and special corner cases that I skipped. That isn't a scenario where you can use issues.


I like that method. Where there is a TODO referencing the ticket number. Makes it easier to find the ticket, or where in the code the ticket references. And helps to ensure there actually is a ticket so it isn't forgotten about down the line.


I agree with this a lot. Issue ID(s) go into every commit in my shop. I'm going to think about how or if issue ID(s) should go into TODOs as well. That might be an upgrade to my existing process for preparing a work surface before upgrade.

Because of default highlighting support, I started using TODO. The most valuable part is the colored flag my tools generate to attract attention to code that needs it.


++ to putting the issue number next to the TODO


Before I had tooling nudging me along, I used +++ as a strong visual cue. Yes, as in +++ATH0.


And I can add additional information next to the todo:

  // todo: todo


This is my real gripe. Let's not pretend "TODO" is the end of the comment.


Nobody did?

The article's goal is clearly to provide a quick categorisation of the TODO, rather than require reading the description to discover it: if I'm trying to debug something and reach a bit of code with a bunch of TODOs it's not going to help me much, if I see a FIXME or BUG I'm going to be a lot more interested.

Sometimes the TODO us sufficient through it context (e.g. a docstring empty but for a TODO stanza is obviously a missing doc), but often it's not and is the documentary equivalent of a goto.


The article is clearly to break our tools and search capacity. If you want to add categorization, do add, instead of replacing, like the GP does.


> The article is clearly to break our tools and search capacity.

Get yourself tools which are not hot garbage? All the ones I use let you customise markers however you want.


> All the ones I use let you customise markers however you want

Customisation requires everyone who ever works on that codebase to also do the customization. Defaults are important


> Customisation requires everyone who ever works on that codebase to also do the customization.

And they can go on the pile of all the others customisations necessary when you don't mandate all the tooling by fiat.

> Defaults are important

Defaults are a tool, when they hinder improvement you discard them.


As long as the second todo is also standardized (TODO: FIXME), so it will play nicely with grep.


The cultural fragmentation of TODO tags is worse than their inaccuracy.

I use the classic TODO, BUGBUG and my own (the last one is usually 'xxx' for brevity, and never in checked in to a public branch). That's it. Life is too short for needless complication.

The PM over there in the corner has just invented eight levels of TODO severity, and will soon multiply the truth by putting them in a database (somewhere), start a set of meetings to track them, and is already talking to tool vendors about building an Enterprise TODO Framework. Dry gulch that PM before you lose your sanity.


>pending deaths on other hills of higher precedence

This is the most obtuse way of expressing a concept. I like it very much.


The IntelliJ IDEs recognize TODO and FIXME comments, highlight them differently, and can show a list with all items. You can also configure additional patterns that should be recognized (although I never did that): https://www.jetbrains.com/help/idea/using-todo.html


Yeah I use the TODO and FIXME with IntelliJ. I don't think it would be a good idea to start using other conventions that would force other developers to set up their IDE to support the same custom patterns as me, though, even though it's nice that IntelliJ supports the option. I'd rather just add more context in the comment.


So, this is why we use TODO as well, even though Godoc supports BUG natively and exports it into documentation. Nothing needs to change, everyone is on the same page. But each TODO is accompanied with a ticket, not just some loose "TODO fixme at some random time I guess?"


Yeah? Well, this is why Jedis do not get their light sabers from Acme Megacorp.


then put the tasks in your project management tool so you can prioritize them. How do you prioritize your todos in your code base? O(n) search?


My project management tool is todo.txt

As far as the hundreds of #todo throughout my code, they are prioritized based on when I'm using the program and decide that I've had enough of a particular issue.

If I sit down to work and I can't think of anything to start with, I do a global search for #todo and pick a random one to work on.


> My project management tool is todo.txt

THANK you. I only need a few concurrences to keep forging ahead with tools that work, but I do need a few.


maybe use TODO: (fix me) ?


TODO and FIXME work with my IDE, whereas none of those other words do. So I couldn't care less whether they're suboptimally descriptive: I'm going to keep using TODO for things I need to do, and FIXME for things that are known broken atm, because those are the keywords that automatically get turned into dedicated lists in my editor UI so that I can work with them right in my editor without any additional tooling or mental overhead.

And if I need a better description: good news, you don't just write "TODO", you write "TODO: add cyclonavigatory imbobulator to fedonculate the explonizle" and you get to see that text so that it's perfectly clear what the task is. There's literally no need for a different keyword to more specifically bin "the kind of TODOs". One bin for "tasks" and one for "bugs" really is enough.

Anything more, and you should start using an issue tracker, not just more keywords. (and ideally all your TODOs are also issues already, of course)


I don't get the hate that TODO comments get (edit: in this comment section, not in the original article). They signal that the person who wrote the code has recognised there is a potential issue, has deemed it not relevant enough for it to be solved right now and wants to summarise the issue in the comment.

If you disallow TODO comments, you will lose that context, or at least it won't be easily searchable anymore. Issue trackers are not a solution because:

- they create too much friction. A developer that is short on time might add two or three comments to suboptimal code rather quickly but would likely not bother dealing with a clunky UI like JIRA, having to write detailed descriptions referencing the exact place of the code, filling out 20 fields and then being hounded by a PM who (rightfully) doesn't understand what "implement foobar() in linear time" or "make Frobulator thread-safe" means.

- Comments are right next to the code, issues are not. I see people pointing out that comments can get out of date, but so can issues in an issue tracker.

- IMO, "refactoring tickets" tend to be the worst tickets, they're rarely fun to work on, they don't include the context for why the refactoring might be necessary or what the best way to evolve the code is, and if someone else is assigned to the issue than the author of the ticket, they might not even understand the intended refactoring. A comment is much more light-weight and optional and anyone who touches the code can read it and decide whether it makes sense to fix it. It's also almost impossible for a PM to know how to prioritise refactoring tickets. IMHO, unless we're really talking about refactoring entire systems, refactoring should preferably be done continuously whenever the need arises, i.e. "first make the change easy, then make the easy change".

- of course, code shouldn't be merged if there are glaring issues that don't implement the feature correctly / could break important things. It's the responsibility of the developer and the reviewer to make sure that this doesn't happen, regardless of whether there are "TODO"s or not.


Hear hear.

Dodging an issue tracker is, IMO, one of the clear benefits of TODOs (or FIXME, HACK, BUG, and family). Especially in low-trust teams or whenever there's a need to avoid the sorts of politics that can arise between roles.

Refactoring tickets are terrible for all the reasons you point out. PMs will essentially never prioritize refactor work over new features unless pressured to, and if so, the work more often than not gets assigned to newer hires and junior devs, whereas a TODO is actually more likely to get picked up by a curious and intrepid newcomer when they're actually ready for it. Should said newcomer stumble across it before they are ready, it can also be a signal that they ought to reach out to a more experienced developer to ask some questions. For devs, refactor tickets may be useless overhead: in time spent writing, time spent defending, time spent estimating, etc. And in return, there's little glory or praise achieved in working on them; tracking too much time on refactor tickets may even attract negative attention from management. Then good luck if your QAs and agile leads are suspicious of any unit of work that a new test plan can't be written for.

A good TODO is sometimes just how the sausage is made.


> If you disallow TODO comments

The author is not saying TODO comments should be disallowed or stopped entirely, and explicitly states that he's not suggesting "use an issue tracker instead".

His recommendation is to use meaningful alternatives, e.g. FIXME, HACK, BUG, etc.


I know, I was replying to the common sentiment in the comment section, not the article itself.


Got it, thanks for the clarification, and I see your edit now.


I use TODOs liberally while I'm working on a feature branch. When I've figured out a partial solution to the problem at hand, I'll implement that and leave descriptive TODOs wherever necessary. My IDE will warn me about them if I skip them before pushing and simple notImplemented()s will go unnoticed.

Sometimes I leave a TODO because a feature/fix must land before a certain date and I don't have the extra time to optimise the code before that. Customers prefer a slow feature over a nonexistent feature. Known bugs can be annotated with a FIXME and an issue number so that nobody will waste time on that part of the code if the bug isn't important enough to be fixed in the current sprint.

That said, "TODO: implement" should never ever reach merge requests or code review. Suboptimal implementations may be acceptable, but missing implementations are just bugs or incomplete code.


This post reminds me of my new book, titled "You Aren't The Boss Of Me And You Don't Know Me: Stop Telling People What They Need To Do From Your Blog"


TODO: implement this system and update all tools to find them in my code base.

/JK

In our group we have the rule to add a task/story/feature ID when you add a //todo in the code. It helped us to prioritize and close todos. If the task was not prioritized for a long time (became overdue) or was rejected the todo is also removed from code. Apparently it was not deemed important enough to implement it and current code became the accepted version.


Just going to pick a single nit.

> you don’t want your project to end up like the Linux codebase with 3000+ TODOs dating back over a decade.

Why don't I? TODOs capture a lot of context that would otherwise be inappropriate or unseen in a comment. They're in all caps and they stand out and draw the reader's eye. They can be completely out of context, whereas comments are typically extremely contextual. They often help explain cases not covered, paths not supported, missing functionality or notes for future contributors. Splitting them into even more comments just makes them harder to find and reason about. When you're writing a TODO, you don't want to stop to smell the roses, thinking about what the future may hold, you just want to blot down the thought in your head and finish the task at hand.

Not to mention that in reality it's quite reasonable: https://livegrep.com/search/linux?q=TODO&fold_case=false&reg...

You be the judge.


Committed @TODO in code is a junk drawer for people who don't like ticket systems. If you are working alone, sure. But in a team, please show your peers some respect and allow them to prioritize/document todos via a ticket system so a product manager can drop it or assign someone else on it. But don't litter the code with a bunch of TODOs.


> "If you can’t tell, this isn’t a super serious post. You can easily describe what you want to do in myriad ways using the classic TODO and beyond."

HN is one of the best discussion sites out there now, but I wish that we weren't so formulaic and repetitive. So many things get over-pushed, simply due to the familiarity of popular structures such as "X Considered Harmful" or "Why I Don't X".

If you actually read this blog post, the thread here is taking this way more seriously than the actual author was.


It feels like the post was meant to spark discussion. Which is has. It doesn't feel like anyone is taking it all that seriously to me. Just discussing what has and hasn't worked for them. I have even learned a few things from it.


And that's why you came to HN for the headlines, but stay for the comment section my friend!


You have to include disclaimers like that or else people on the web will come after you. But yeah, the hope was that it would spark some discussion on the topic.


There's not really a lot to discuss.

Most tools support automatic aggregation and review of code comments starting with "TODO". Maybe some of these tools can be configured to support other prefixes as well. But they all support "TODO" by default, and it's pretty trivial to just put your shorthand descriptors after the "TODO".

Also, if you're pushing commits with a ton of "TODO"'s, then you're probably doing something wrong. Many tools will warn you by default, and many CI/CD pipelines will block your commits altogether. If something is small enough to be addressed right now, then you should address it right now. If it's large enough to require addressing later, then it should be a tracked ticket rather than a loose code comment.


I WILL use todo for everything! But instead of committing them inline, I will dump them into a TODO file that is ignored by the VCS. If this file starts getting too big, then I'll move some of the long-standing todos out to an issue tracker.

> Why not just go straight to the issue tracker?

An issue tracker adds a lot of overhead. It's sitting on a different system, so you have to have a separate window open. It's public, so you have to spend time producing a comprehensible issue. Every action is a commitment. Internet access is essential.

Meanwhile, TODO is just a file, so it can sit right next to your code. Its private, so you can just stream thoughts right into it and move on. Adding an item is as simple as typing out some lines, and removing that item is as simple as deleting some lines. Need to search? Just grep it. It's fast, and it doesn't leave a mess in your code.


would it help having a TODO inline linked to an issue tracker automatically? so you would never have to switch context.


IMO these are anti-patterns that makes code smelly.

A practice I like to follow is to document "hacks" and create tickets for TODO items. In my experience, this has scaled better with the growth of the team and also allows for knowledge sharing and brainstorming when planning.

For TODO items I used the "eisenhower matrix" to decide if I should create a ticket for it or not. Where TODO items that are not "urgent" nor "important" are simply ignored until they reemerge again.

There are few phrases that I like to mention when I see devs add TODO comments:

- if in doubt leave it out

- every line of code is a potential liability that needs to be maintain and tested

- in the future requirements may be different or no longer relevant


Why was the title edited to say the exact opposite of what the article says? This practice seems to get a bit out of hand recently.


According to the "HN guidelines" [1]

> Otherwise please use the original title, unless it is misleading or linkbait; don't editorialize.

So, "Stop using" could be considered "linkbait", which could be why it was changed to just "Using".

It's ironic that this has the effect of misleading the author's intent...

[1] https://news.ycombinator.com/newsguidelines.html


I noticed this as well; at first I thought this was a tongue-in-cheek response to the "Stop..." version.


I'm not sure - I didn't edit it and I don't know how to fix it


HN has some rules for automatically fixing up headlines. Usually it edits out small words like "the" and "a" at the beginning of a title.

I have no idea what the rationale for this is, especially considering the potential for corrupting the emphasis of the original headline, like in this case.


My pet peeve is `XXX:`, which I see with distressing regularity in the codebase I work in. It’s non-specific, but vaguely ominous. Is it a TODO? A warning? A bug? An incantation to ward off evil spirits? Tell me!


I don't know if this is the exact incantation, but some IDE extensions will recognise some special comment annotations. TODO/FIXME support is in pretty much every IDE, but there are some special codes that some IDEs will recognise.

Visual Studio (not necessarily Code) will recognise TODO, HACK, NOTE and UNDONE, for example.

Java conventions mention XXX: https://www.oracle.com/java/technologies/javase/codeconventi...

    10.5.4 Special Comments
    
    Use XXX in a comment to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken.

Using XXX in comments goes back to 1978, according to https://www.snellman.net/blog/archive/2017-04-17-xxx-fixme/

I'm not a huge fan of XXX as a warning, there are more descriptive names in caps available that your IDE will probably even autocomplete after using them for a while. However, the practice is common enough that it's just a General Programmer Thing, kind of like how some people prefer /* */ over // because they're just more used to it.


I use XXX to mean "this code is ugly and not the intended design, but I don't see a great way to fix it". If I did, I would leave a TODO with steps. The XXX is a formalized "ugh", a note for anyone reading my code later to glean that I was unhappy. Often times the hardest thing about reading a codebase is rebuilding that mental model on how the code is ideally supposed to fit together at the high level, and an XXX explicitly marks a conflict between the code itself and that vision, and explains why.


"XXX:" is short for "BULLSHIT:" or other profanity to me, generally imply that life sucks.

usually to indicate some horrible hack which is required because we can't quite blow up the codebase to fix it all, and i'm not thinking of a simpler solution today.

it also exists to point out that even though the code looks maybe mindlessly overcomplicated that someone shouldn't just come in and refactor it to make it simpler because it'll blow up some edge condition if you do that. They're the long-term nuclear waste warning messages of a codebase.


Maybe it's used to mark NSFW code (which your boss shouldn't see)?


We had a recommendation in one of my previous companies to replace all TODO's with XXX. Their rationale was that the TODO tags sounded like an unfinished product to the customers. So they wanted to replace all those TODO labels with XXX so that the customers wouldn't find them when grepping. Even if they find a XXX label while reading the source they wouldn't have any clue as to what it is.


I use it occasionally as a heads-up about tricky functionality, or to point out something that should be read by future developers, so yes, like a warning. It's similar to `NOTE`, but more important. There's nothing to be done, so `TODO` wouldn't make sense.


Why not `IMPORTANT:`?

I haven't seen `XXX:` anywhere, but it's immediately disconcerting as the icon is meaningless. If I have to reach-out to you to discover the meaning of some word you use, it's a bad word.


> Why not `IMPORTANT:`?

Like others mentioned, it's not as an established convention as `XXX`. And it's much shorter and quicker to type, particularly convenient when you just want to rant about something, which is the usual use case for `XXX`. ;)

At the end of the day, these labels are meaningless unless the entire team is following the same conventions. So using whatever your team agrees with using is the most important thing.


Does it really need to be something more important than NOTE? If you are working on the code you should be reading that NOTE anyways, so why not use a word with more specific meaning? Or even just IMPORTANT. Before this thread I would have never known what XXX meant, having never seen it before.

I suppose if its defined somewhere as a standard for everyone working on the code it may make sense. Just doesn't feel very intuitive to me.


I use it with parenthesized clarification. So `# XXX(dependency-version): Reason why we can't have nice things` is code that can be updated when `dependency` of at least `version` can be assumed. The clarification is there so that if the reason itself goes away, we can just remove the conditional. Repeat for things like `cmake-3.23`, `macos-10.14`, `python-3.8` and so on. It's just an easily greppable string and Vim highlights it differently.


I wonder if these types of articles would get a lot less attention if the title was something less assertive like "Consider replacing TODO with something more specific".


Oh for sure. I've posted on HN plenty of times and never gotten any comments - I post something short and "hot take" and suddenly get top 10 lol


Ok, but hear me out: what if I don't use any of these, just put ToDo everywhere, and don't waste time thinking in what category the current todo should fall on? Then I book 15 minutes at the end of each day or even week to categorize everything and put into a backlog.


At some point convention at Google on many teams I was on switched from:

TODO(username): blah blah

to almost-mandatory:

TOOD(bug#): blah blah.

Gonna write a TODO? Make a ticket for it, and follow up


I've really liked using a template that looks like this:

    // TODO ${username} $[date} (ISSUE) - message
Having a who and a when is very useful for quickly determining what it's about.

The username is helpful for myself for quickly finding my own TODOs, the date is useful for others, as if the issue is so small nobody has bothered fixing it for years, then odds are it's probably not ever going to get fixed and then the TODO can probably be removed.


been using this approach for a while. it also comes up in PRs to encourage either fixing the issue now, realizing it doesn't need the TODO, or saving it for later. and +1 on searchability when searching ISSUE-XXX and seeing all relevant comments. Would make for a good tool


At our company, we have a rule: when you want to add a TODO you must create an issue in the issue tracker (which is added to the backlog) and place the issue ID after the TODO. This way you have a full context/description what was the intent (is it a bug? is it a feature we abandoned for now? is it a temporary hack?) and since it's in the issue tracker you can do all sorts of things such as sort/group by tag, date, priority etc. It's also easy to find all places in the codebase which need to be touched, by searching for the issue ID.


To me, TODOs are the equivalent to keeping thousands of tasks in a growing backlog. It just adds noise for stuff that probably won't be addressed ever. And if it is addressed, chances are that it will be from a new task. Just forget it! If it's important, it will come back on its own.

I just don't write TODOs in my code, as I have never seen a useful TODO in a codebase... The worst being "TODO: improve this". Sounds like a way to say "I wrote shitty code, I know it, please merge it anyway", which is completely useless IMO.


> Sounds like a way to say "I wrote shitty code, I know it, please merge it anyway", which is completely useless IMO.

This is not a TODO issue, this is a merge criteria issue. TODO and its variants are only as useful as the process enforced surrounding their use.

If a dev team agrees that code can't be merged until certain types of TODO-variants are addressed, then the comment may be useful.

But of course, if no such process exists, they may not be useful. But that's a team/process issue, not a fundamental problem with using TODO comments.


No I won't. TODO is much easier to remember than DOCME or TESTME.


I try to never merge TODOs in master. I do use these in feature branches, but if it was not important enough to fix while working on a PR and there is no ticket for it, the probability that it ever gets done is low and it ends up cluttering the code. Considering I want to delete my TODOs before I merge, it's much easier to cleanup if it's all the same line prefix (TODO).


Hmm, in Spanish "todo" literally means "everything"...


"We've been working on this project for a while, what's left to go?"

"Just todo."


Yes, just looked this up to confirm my rusty recollection.

https://www.collinsdictionary.com/dictionary/spanish-english...


We're not in Kansas anymore TODO fetch ruby slippers


Hum... Ok, just standardize those names so we can have tooling support, and make them as fewer as possible so they are easy to remember.

Honestly, the article has a very expensive proposition and a completely unsatisfying reasoning. If you want to add some explanation, well, add it after the tag. The tag is exactly that, a tag, not some part of your comment.


I'm a fan of using the extensions the author mentioned when I'm exploring a problem space. I scaffold out the overall design for the problem in terms of modules and functions so that the code reads correctly, type checks, and works for an extreme subset of inputs. Anywhere that I haven't actually implemented the real solution I put in a "NO-MERGE" comment. Then when I feel that I've solved the problem at that scale, I can go through all of my NO-MERGE comments and implement them correctly. As the name implies, these are never merged in to main/master. They just act as bookmarks which should be obvious when reviewing my changes.

Personally, I try not to commit any TODO comments. They're sort of like warnings. Unless you're religious about clearing them out, they're just going to build up and be ignored.


This is silly to me - not because using multiple tags is better or worse, but because # TODO is something I see as primarily personal shorthand, and I think it's counterproductive to prescribe tags for people to organize their own code with. If my brain likes "TODO: fix edge case" and your brain likes "FIXME: edge case," that's okay.

I guess this is relevant if you're using TODOs in the main branch, but I see that as rare. There are very few times I've had someone else pick up a TODO I've written, or vice versa. In my current team, if we're passing a To-Do/bugfix/enhancement to someone, that becomes a ticket and/or a Slack conversation.


For unimplemented stuff / placeholders I highly recommend exceptions instead of TODOs in any form (if suitable and your language of choice supports that). E.g. in Python:

  def my_fancy_function():
      raise NotImplementedError


But why only one or the other? The TODO is for your IDE to tap into so you can quickly and easily find outstanding work before the code is ready to be submitted as MR/PR (most IDE and even many simpler code editors have TODO/FIXME listing built in).

The exception is for runtime behaviour until the TODO is resolved: it's something you do mostly for yourself, not others. By the time others see your code, your TODOs have either been addressed, or they're acceptance criteria for follow-up work in your project tracker.

And that brings us to the third part that we _also_ need: the issue that the work the TODO talks about is for. Either as a checkbox task in a larger piece of work, or if it's big enough, taking up the entire issue. (because good project management means knowing what tasks are required/which work is outstanding, without opening a single file)


I would say “Don’t use TODOs (in your code) at all”. They are just “broken windows” in your code. If something is a bug and you think that it is important to be fixed - just do it. If you think that something has to be done but it is out of the scope of your current task, note it down somewhere and take ownership of making it happen one way or another. Leaving a comment in your code just puts this responsibility away from you. In my experience this does not work and those type of tasks just pile up.


I use them for when I'm working on code but someone needs me to switch to something else. It's a great way to improve context switching. Otherwise I come back to the code and go, cool where the heck did I leave off.


Right now, I just use TODO along with a description. But the thing that has helped me and my teams most is adding a date and a name to each todo. For example, // TODO (03 May 2022 chap): This can be optimised.

The date really helps because many times the TODO was written for an earlier design, and the todos haven't been updated. Many times a lot of time has been saved when trying to figure out the context of a todo.

Same for author. Helps to know who made the note, in case any additional context is needed. Though often it is you who made the comment and you've obviously forgotten...


If you're using a decent version control system, the name and date can be skipped in favor of a quick blame when you actually need to know.


I guess that's another way to go about it. I don't know how git deals with reindenting, refactoring etc, and you might lose context, but you could probably find it again.

It's kinda nice having it right there in the code though.


I use an iterative blame tool (magit-blame in Emacs) and it generally does pretty well for me.

I prefer having the author out of the way and looking it up when I'm curious. I can see how others might prefer the opposite.


If you have to subcategorize your TODOs you probably have too many TODOs.


I don’t think it matters that much how they’re labeled as long as they are easy to get rid of.

Before I ship something to production I try to get rid of all TODOs. Sometimes this means rewriting it as documentation of weird behavior, often it means moving it an external backlog, once in a while it is actually doing the TODO.

Once a TODO ships, it is effectively a WONTDO because nobody is going to want to touch that hairy code and if it works it works.


The original Java style guide from 1997 defined "FIXME" and "XXX" in section 10.5.4 https://www.oracle.com/technetwork/java/codeconventions-1500...

> Use XXX in a comment to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken.


To each their own. Mine is:

TODO is a linting error and should not exist when it’s final PR time. We use them for our own feature branch dev work.

Any item that’s a “do later” needs a URL for a ticket/issue in the comment. These are very rare and discouraged as usually the issue alone is enough. Don’t need to mention it in the code because even the location of the mention can basically be an opinion on how to solve the problem.


TODOs to me are pretty useless. Usually, they end up lying around for a long while and just create clutter. Opening a ticket is usually much better


My favorite tag is UPSTREAM to annotate workarounds forced by 3rd party libs or otherwise. Normally I include the link to the associated GitHub issue or SO post.

Tends to be the most useful in-code comment because if someone comes along and "helps" to refactor the "weird" code, they could accidentally undo the workaround and get stuck in the same loop the original author was in.


This article seems to have been written by someone who doesn't use grep.

I don't want to remember a complete ontology of greppable signifiers. I would prefer to just 'grep -R "TODO" <dir>' or 'grep -R "TODO(zomglings)" <dir>' than use a more complex grammar as the author suggests. We can stuff those kinds of semantics in the TODO message.


Please don't.

If you're reading a sentence in a TODO you can decide what it wants you to do, it's bizarre to claim the reader will be less confused if the sentence was merely labeled differently. This reminds of using emojis in Github issues instead of using a universal up/down vote to count the usefulness of an answer like Stackoverflow.

Please don't ruin programming further.


I like the concept. IntelliJ IDEs (which I primarily use) recognize both TODO and FIXME by default, and can be configured to recognize other values.

Admittedly, I probably won’t adopt these new values since I tend to attach a Jira ticket and a few sentences to many of my TODOs; however, I can see how the concept would help some teams/individuals who tend to be less verbose with their comments.


I really like this! Though I'm still going precede everything with TODO like so:

    TODO([person], [subtypes...]) [message]
Just as a catch all, in case w/e tool (or other people) don't grok the subtypes of TODO, or in case I encounter a new subtype I'd like to use. And at this point I think TODO is pretty ubiquitous.


I believe that categorizing comments will save some time down the road if you're specifically looking for something like "BUG". However, searching and aggregating all comments becomes more difficult, which is, in my opinion, one of the main benefits of using "TODO".


(unless you’re spanish)


I use TODO: as a specific type of comment, a message to future developers about stuff to do later that isn't a bug or feature:

a) Suggestions for refactoring: TODO: move this to its own class

b) Known future work: TODO: remove this when legacy accounts are deleted

c) Warnings: TODO: this probably doesn't scale, suggest XXX instead


If you have so many todo’s you need a syntax to define them more precisely, perhaps use less of them?


I would strongly argue against this. Not only TODO is easily searchable as others have also pointed out, but also in some IDEs you can open a TODOs window which will aggregate all of these so that you can easily keep track of them (e.g. Visual Studio).


Don't tell me what to do! Besides, there is a million other mountains, and battles to die on.


If it helps I think of todos as thoughts for future programmers so I try to give more context including category and priority:

TODO(security, p1, blocking): login must be authenticated

TODO(perf, p3): update can improve to O(n) if needed

TODO(data, p1, blocking): this db insert should be retried on failure


On productivity hack: I routinely put “//TODO: you are here. (Description)” in the code before I close it for lunch or the day. This way I can pick back up right where I left off. Saves a few mental threads context switching.


There was a tool a while ago that let you track bugs and implementations with comment tag inside your code. I think it sounded like "artifact", but I can't find it. I think it was abandoned, but are there other tools like that?


Great idea overall.

Rather than entirely replace "TODO" (which would then require multiple searches when a single one now finds all instances), consider augmenting it instead.

E.g., TODO-FIX, TODO-DOCUMENT, TODO-ADDFEATURE...

(or, if you prefer, abbreviated versions of such tags)


But then we have to remember all the different tags we’ve used! Sometimes months later!!!

Search TODO wins


I like to use DEBT for times when I'm writing code that I know are poor practices, and will need to be refactored, but I'm in a mood where I just want to get something built that I can see and UI test.


HN in 2023:

"Conventional Codetags: a specification for structured TODO comments"


Docs should be written along with code, while the problem is still fresh in your mind. If there's the need for DOCME, there's possible something wrong with the way a team is writing code.


I have put in many that look like

`TODO: can’t foo because bar. workaround with buzz. tracking: github.com/issue/1234` or whatever.

Every once in a while I go back through and clean up what I can. I think this is good.


One of my favorite things to do is search a larger codebase for TODO and see what made it into production.

I have hopes of one day being a more competent engineer and being able to go squash the todos.


Use a TODO that has a forward link to your issue tracker.


My system has become:

TODO (never make it into `main`)

SHOULDDO (may have been TODOs in a previous life)

COULDDO (effectively pre-emptive strikes for code review)

I don't know whether this is a good thing or a bad thing.


I really like TESTME from article as pre-emptive strikes for code review :)

This way you get all reviewers that write "any unit tests for that" covered and any brogrammer will know it is strong alpha male territory.


FYI, the title of the post is "Stop Using TODO For Everything" which is very different from "Using TODO For Everything".


Why is this link different in a misleading way from the actual title of the blog post? Doesn't HN usually avoid that?


TODO: add a comment here later


would it be valuable for anyone to have an inline TODO / categorised TODO automatically link to an issue tracking tool? I'm building one, and this kind of feedback would be very helpful.


Broke it down to 4 annotations: DEPRECATED:, FIXME:, INFO:, TODO:


Visual C++ in the '90s already supported all of those..


How about stop telling people what TODO. Especially when the complainer can't even comprehend that TODO can be specialized.


@TODO: Stop using TODO


Who cares?


I'm skeptical of use of TODO in general, because we rarely know what the future portends. To say "TODO" is to assert what must be done in the future, when in reality all we can typically say is "NOTDOING". That said, "TODO" is well-understood by a lot of editors, so it's often useful to just drop that word in the source code to make it easier to find.

A more reliable approach is to:

1. File a ticket, and

2. Leave a comment in the code linking to it:

    // This code does X, but it'd be better to do Y. At the time of writing
    // fixing this doesn't seem to be an issue worth fixing.
    //
    // See: https://bugtracker.example.com/...
It's very difficult to write code that correctly predicts the future, but it's easy to write code that accurately describes the status quo at time of writing.


> To say "TODO" is to assert what must be done in the future.

This isn’t any different from filing a ticket. There’s merit to keeping all of your work in your issue tracker, but this isn’t part of it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: