I thought this technique was such common knowledge that I kept waiting for the punchline in the article. It was a good reminder that even the simple stuff deserves to be written about and revisited every so often.
>>>The great thing about TODO comments is that, as a very old programming trick, they are already supported out of the box by most tools IntelliJ, SonarQube, Rails, CodeClimate and I guess many others. Only one day after I refactored to TODO comments, a team mate fixed one that had appeared in his IDE’s TODO tab
My advice is to never place TODO comments in your code. It will become a graveyard for TODOs and annoy fellow programmers who come across it for years after it was written.
Instead
1. Quickly experiment with refactoring but stop if it feels wrong. We often underestimate how quickly we can improve the codebase. It's often better to try something quickly than waste time planning to do it.
2. Defer if it's a big refactor or you're on a very tight deadline. Write a reminder in your physical notebook so you don't prematurely pollute your board. If it feels high priority after that and you still haven't had time to do it, then make a chore ticket for it.
Placing TODO and ASAPs in code helps ensure you don't leave any loose ends, and if you call another developer onto your feature branch allows them to get a feel for how you're getting on and how complete the code is.
Using a physical notebook distances the workload from the code and hides the fact something is incomplete from others.
A TODO graveyard can be prevented when you review the code - a developer who thinks a feature branch littered with TODO annotations is complete code is either dreaming up future use cases or failing to complete the work assigned.
> Using a physical notebook distances the workload from the code and hides the fact something is incomplete from others.
Exactly. In fact, I use both (except the notebook is an org-mode file, not a dead-tree book). TODOs / FIXMEs in code are for things very context-dependent and connected to code, for which it's important to see them in surrounding context. In more abstract cases, I just log a task in my notebook, to be done later.
Examples of both - code:
//TODO resourcify
(i.e. move to external string resources database later)
vs. notebook:
** TODO Refactor the refactor of the SomeClass class.
--
Also, often TODO / FIXME comments serve for me as anchors in some larger refactoring processes. I tend to label them specifically for easy grepping (e.g. with unique Unicode chars like ). The point is, refactoring process may take few days, during which I also may need to do some other tasks, so whenever there's a piece of code that needs to be redone but not right now, I tag it for later; I can then use grep/IDE search to check if I didn't miss anything.
I think you're both right. It's okay to have them locally or on feature branches for communication and note taking purposes. But they should never live for any prolonged time in your production code.
TODOs are ok when you're keeping track of what you were doing the previous day and what have you but for anything long term they are awful.
If you want other developers to see these TODOs in mainline, then they shouldn't exist and instead be in your teams project tracker.
Would you put every task as a TODO in code? No of course not. Its not easy to manage by non-coders, low visibility to anyone not in the file in question, no priority or organizational quality, no way to prune or plan these TODOs, etc etc.
If you would wouldn't put every task in a TODO, why put any task?
If you invest heavily in TODOs you just end up with things that should tickets and aren't or vague desires that would never end up as tickets because they're not well thought out anyway.
The argument isn't that TODOs should replace tickets. There's a place for both.
Often, by the time you officialize a TODO into the ticket pipeline, you could've just fixed it yourself. But the reason you dropped a TODO was because you were already busy with something else more important.
TODOs just sit at a local, unofficial scope in the code. I'm not sure what kind of things you put into TODOs, but if you were to generate a ticket from each TODO in the code I work on, you'd have generated a bunch of low value ticket garbage.
The problem with a rule like "no TODOs allowed in the code" is that TODOs are issues that aren't usually worthy of a ticket, or at least not the time to turn it into one at that exact moment. You'd just be blind to more issues. Not a reason to pat yourself on the back for 'clean code'.
This is classic Black and White engineering advice, which shuns pragmatism because some idiot could come along and make a mess of the codebase. If someone is capable of displaying such bad judgement for such a trivial matter then they shouldn't be working on the code in the first place.
Take the Tensorflow codebase (and Google and Microsoft code, and linux in general). There are currently ~1,028 TODO's in Tensorflow, most of which refer to a particular engineer in the form TODO(<name>):<comment>. This is pragmatism and good judgement in action.
Software engineering is all kinds of shades of grey, competing considerations, trade-offs and balances. It's what makes it interesting.
I disagree. Working on a large software project with many programmers, it is very useful to see what other programmers intend (or just hope) to change, even if it is just to get more of a glimpse in to the intention of the dev.
I find the usefulness/annoying ratio to be very high.
The problem is not in how these issues are recorded, but whether they will be acted upon. It is all very well to say just fix them immediately, but we all know that will sometimes (often?) lead to issues simply not being noted. Putting the issues elsewhere is no guarantee that they will be acted upon, and any rule you make to try to get them addressed, such as fix before check-in, will again lead to them not being recorded in the first place. In fact, if you find TODOs in code to be an irritant, perhaps that is the best place for them!
The code is where TODO's should live. Anything else can be separated from it. It'll help people understand areas where technical debt was intentionally incurred and expose them to the tradeoffs involved at a high-level.
Also, not all tech debt is solved by refactoring.
TODO comments aren't suitable for tracking all technical debt, but they're good for targeted instances.
This is exactly my stance on the matter. Don't litter the code with unnecessary comments that will never get acted upon. Instead, make a story in your bug tracker and act upon it.
Not only that, but bugs come and go. People add a bunch of tech debt issues into the system, then a bunch of feature requests, possible bugs, and whatnot gets added. Then some big milestone or release comes up and everyone filters through the list, deciding what to fix and what not to. And then anything that doesn't need to get fixed "RIGHT GODDAMN NOW" often ends up on the ash heap of history, never to be seen again. And then years later someone looks at the code or runs into a bug and remembers "oh yeah..., hey, we should fix this eventually".
If you want to fix/change something eventually at some indeterminate time in the future then comment TODOs are a good place for that sort of issue to live.
TODO's are for things that are optional to fix and probably won't be fixed. Sometimes not fixing something is the right move, but you leave a signpost that you deliberately skipped it. Someone else, later, can pick it up, if they choose.
Whether fixed or not, it's valuable to future readers to know there's a gap.
This is exactly what I use them for and it works well. They are like the "falling rocks" signs on roads. The "TODO" is to make the entire cliffside completely safe, but as long as everyone is watching for rocks when driving (coding) in this section, that suffices.
I will usually also include //HACK comments with a little note as to what is broken or what my assumptions were at the time of writing, for things that I believe are likely to cause breakage later on.
TODOs are for optional/longer-term things as you described, like inefficient implementations because the current assumption is that it will ever only operate on 20 elements.
HACKs are more along the lines of "hey if you're debugging this bit of code, your issue is probably here"
I tend to use TODO for features/functionality I'd like to add, and FIXME for existing functionality that's not doing what we want. Obviously there's a fuzzy line there.
Issue trackers are good for long treatment and allowing people to prioritize and schedule fixes for technical debt. They're also somewhere that issues might go to die - in many orgs, it's common to basically ignore anything in the backlog that isn't being actively championed by a team member or customer.
The nice thing about putting todos in the code is, somebody will see that the next time they're working on that chunk of code. The bad thing is that they're highly localized, and frequently give little space to give a full explanation of the problem.
The combination solution that really does get you the best of both worlds is to create a ticket, and then reference the ticket # with TODOs when there are bits of the code that are influenced by that technical debt. That way if you're seeing a todo in the code, you can easily get to a central ticket with more information. But also, when you're working on one of those tech debt tickets, you can search for the ticket # in the code base to verify that you really have found all known (by which I mean, somebody cared enough to make a note of it) places where the tech debt is manifesting itself in the code. Also, tech debt is less likely to become a dead letter. Programmers read the code incidentally to their work. The only people who habitually read the ticket queue incidentally to their work have PMO certifications.
> Issue trackers are good for long treatment and allowing people to prioritize and schedule fixes for technical debt. They're also somewhere that issues might go to die - in many orgs, it's common to basically ignore anything in the backlog that isn't being actively championed by a team member or customer.
The nice thing about putting todos in the code is, somebody will see that the next time they're working on that chunk of code. The bad thing is that they're highly localized, and frequently give little space to give a full explanation of the problem.
I used to think the same; however the reality is if nobody cares about a given issue it's not an issue worth working on. Same with TODO or other notes in comments.
There are many reasons to not work on something immediately beyond "nobody cares". I've frequently run into situations where some small hack needed to be used to work around a shortcoming in some major module. Fixing that module might not be something that can be done right away, either due to scheduling or resource constraints, or because that module's owned by some other team, or it's a 3rd-party component, or whatever.
When that thing finally does get fixed or upgraded, it sure is nice to be able to just look up the master ticket for "Hacks to work around X" and easily find all the little things you can clean up right away.
But, of course, if your tooling and team procedures force you to choose between "fix immediately" and "DFC", I suppose that would result in a lot of decisions to not even worry about technical debt. Over time, you could probably even lull yourself into thinking it was never technical debt in the first place.
There's different sizes of TODO. For anything beyond small cleanups, yeah, an issue is probably warranted. But, filing tasks in the issue tracker aren't always the best solution either. They often become out of sync with the state of the code, and who's going to trawl through all of those low-priority issues on a regular basis? To mitigate the de-synchronization, I tend to embed links to the issue in the comment like: # TODO: Frob the foobar issue #4376
The only way an issue about technical debt becomes irrelevant is the debt is not there any more. I don't know how others treat an issue tracker; on my team, we go through issues at the start of every sprint and possibly re-prioritise. Issue became irrelevant? Close. Move on.
> They often become out of sync with the state of the code
I try to write a test when I open a ticket, demonstrating the desired behavior, and mark it such that it's checked for failure (so we notice if we've fixed it in passing) unless an environment variable is set to the particular ticket number. Sometimes I also include a test demonstrating current behavior - this helps surface the tickets if someone is working on something related.
+1 for using the issue tracker. Creating a new issue in your tracker should be close to zero effort (if it's not, your company has a bigger problem than technical debt). And I would imagine in the vast majority of dev shops nowadays, you always need to cite an issue when you commit your code, so why not create it as soon as you identify the technical debt?
Putting things in the bug database is officially transferring responsibility for the issue to the management or the team. Give me permission to work on this thing.
It's a cop-out, and unfortunately a hallmark of a class of developer most of us miss. It took working with roughly the same group of people for four+ years, twice, before I even noticed them. It's probably two groups with similar symptoms which I think contributed to my confusion.
First group are the fakers. They are people who want to appear high minded and will agree with all of your plans for reducing tech debt, except the first time there is any schedule tightness they'll throw it all away and claim that they wanted to do more, But The Deadline. You can spot these people because the next time there is schedule slack due to requirements not being ready, they will complain about there not being anything to do. Meanwhile their legitimately conscientious peers are already 12 hours into some refactor that the boss didn't tell them not to work on.
The second are Flow junkies. There are people on your team that do heavy lifting. Big rework, new architecture, they can do amazing things, occasionally startlingly fast (doing judo on the code to make it do things you didn't think it could).
Problem is, they are so addicted to The Flow that they have to wrestle dragons even if they don't exist. They can take the code far in directions nobody else understands, which must be because they are smart and you feel a little imposter syndrome.
But what really happens is that they make the code in their own mental image because they can, and that stacks the deck so that they are >3x more productive in that code than everybody else. This creates the 10x myth, because they are actually about 3x more productive in arbitrary code, but 10x more productive in code they've arranged so only they can really follow it. In the middle of the Flow stopping to clean up pesky things like argument consistency might break the Flow,
Their tell is that they often "don't have time" to fix annoying inconsistencies or bugs in their code, expecting people to avoid them, and yet they seem to have plenty of time to reinvent the wheel, writing frameworks or event processing systems when we already have tons of those to chose from. Because those Big Problems have the sort of time and space in them to both require and allow for a Flow State to happen.
I know this type because I'm an ex Flow junkie. I spent too much time studying ergonomics and realized that just because I could follow the code easily didn't mean it was great code. Though I could achieve Flow while doing truly annoying bookkeeping refractors, over a long period of time I found it harder to achieve the Flow state. Maybe I got old or maybe I was less motivated or maybe open offices killed it, who knows,
So I subscribed to the philosophy of, "a rising tide lifts all boats", and am just fine being a 3x developer who makes the code and process more productive for others.
> Then, there needs to be awareness and a sense of urgency. Technical debt accrues interest.
An alternative interpretation is that technical debt depreciates. That is, in a Darwinian way, clearly the product survived WITHOUT implementing the changes someone thought it needed. So is it really technical debt, or just baggage?
Sure, and sometimes you have to declare tech bankruptcy, and just do a rewrite from scratch (often accompanied by a switch in framework or programming language).
Whether it is "baggage" or "debt" depends on whether it is accumulating interest (that is, it makes other changes such as adding features harder and harder to do).
Depends on the type of project. If your service is down, you can schedule some maintenance, fix whatever needs fixing and come back up after few hours.
But if your service is large enough, a maintenance window costs you money, reputation, customer satisfaction and makes you breach contracts and service level agreements... you may want to find ways to minimize maintenance downtime.
In that case you will want to make your code straightforward enough so mean time to detection and mean time to repair is low by emphasizing maintainability, namely, clean code with accompanying tests.
+1 Though I do leave the occasional TODO or FIXME comment in code I prefer using deprecation attributes so that it results in a compiler warning. I spend a lot of time in Xcode so for me I like that autocomplete shows the method with a strikethru and the compiler warning is highlighted inline. It becomes glaringly obvious to everyone that we're adding to the technical debt by using the API.
My way is simple - I occasionally grep the whole codebase for "TODO", "FIXME" and "HACK", and review the results, trying to either immediately fix them or turn into actionable items.
At my $dayjob I do Java, for which the IDE also lets me conveniently view the TODO/FIXME entries. I also have Sonar, which reminds me of them through low-importance warnings.
Thanks for the link, it looks nice. I'll consider it if I ever start doing anything in Node. At the moment, however, I prefer it simple:
In Fish Shell I have:
function grp
grep -rni $argv
end
and I simply do "grp todo", "grp fixme", etc. Example output (it's actually also colored):
src/main.lisp:63: ;; TODO FIXME introduce at some point a mapping for page list -> generation function, or something.
src/main.lisp:89:;;; FIXME deprecated
src/main.lisp:94:;;; FIXME unused and probably throwaway
src/site-components.lisp:9: ;; FIXME use some page structure map to map from (name language) to base filepath
src/site-components.lisp:31: (let ((colorize:*css-background-class* "no-paren-fx")) ;FIXME make configurable maybe?
That's good enough for me :). Also I have appropriate highlights set up in editors & IDEs I use :).
Many IDEs even give you the option to add TODO comment keywords as you see fit, so you could add HACK to the list directly. It also provides room for more specific and/or interesting keywords like REFACTOR or DESTROY.
When I was using Eclipse I actually put a few swearwords on that list just in case - sometimes someone on the team loses their temper and leaves a nasty comment in the codebase.
Meanwhile, at the Indian contracting company where I currently work, I came across a few lines of code in a phone application that no longer logged data to a log file. I was told that it had been there for a number of years. As I went to instinctually remove it, I was told by my supervisor that "we don't remove anything unless we get a Code Cleanup task". Cleaning up the code now would be "Out of Scope". It's no wonder now how this project has 1M lines of code and 10K files... Garbage in, nothing out.
Engineers who only do exactly what management tells them to do should be thrown out with the head first. If management knew exactly what has to be done there wouldn't be a need for engineers in the first place.
This pre-supposes a team of people who care about technical debt. I remember Eclipse in the early 2000s was already doing this (FIXME, TODO and something else IIRC).
In my experience there are lot of productive programmers who, overall, add value (stuff gets done, it's not a bug-infested disaster) but simply don't care. Might not even have heard the expression technical debt. Might care more about short-term reputation wins from Getting Stuff Done. They aren't going to leave TODOs.
On my team at work we require all todos to link to a tracking issue (think like JIRA, etc...)
That way it's
1.) Clear what the context on the todo is
2.) It's clearly in our backlog and can be prioritized accordingly.
We have some scripts that run at build time to verify all todos have the appropriate issue as well as manual code reviews on all changes and I honestly don't remember the last time it was done incorrectly.
Interesting that the author highlights CodeClimate's "support" of TODO comments via the FixMe engine.
The problem is that the TODOs get flagged as failures in the context of a pull request and require a manual override. The overall attitude in the tooling is TODOs as a code smell or problem vs. a solution.
Maybe this is not a big deal (since you can interpret the information however you choose) but it creates cultural resistance to embracing TODOs. We've recently started dabbling with TODOs again on my team but I still haven't overcome a bit of guilt I feel, like maybe "I'm doing it wrong" -- even though I think TODOs are a perfect fit for highlighting small tidbits of technical debt as the author describes here.
This is really good feedback, which we are addressing. We're going to change things up so that by default TODO issues are emitted as "Info" severity instead of "Minor", and we are going to change our PR integration so it does not fail PRs on "Info" issues.
More in reference to the comments here than the actual article, but TODOs in the comments can be used to transmit what I find to be useful information: $THING was on the writer's radar, but $THING is not handled (correctly or not) in some non-obvious manner.
If your project uses them to indicate e.g. things that can not be merged into master, then obviously that's one thing, but when they're simply comments, the hate here seems misplaced. Other than (maybe) redis, I don't think I've ever seen code that did not have "potential things to do" that would have been nice to see commented.
In my opinion, this is a bad practice.
1. It prevents discussion. Whomever wrote the "TODO" solemnly decides what is there "TODO", without the ability to discuss options.
2. It does not allow prioritization of tasks easily.
3. You need yet another tool to discover issues.
4. It prevents ownership of an issue.
All those issues have already been solved with a simple ticket system (github issues, JIRA tickets etc'). Why reinvent the wheel? What is the benefit here?
> All those issues have already been solved with a simple ticket system (github issues, JIRA tickets etc'). Why reinvent the wheel? What is the benefit here?
The #TODO comments live close to the code. If it gets updated (whether that's an actual fix for the tech debt while working in the area, or removing code altogether due to refactoring, there's no guarantee that the ticket will get updated - and then you spend time trying to figure out which actual tech debt tickets are up to date or not.
It also means that they're easily discoverable - you can stumble on one while working on something, without having to hunt through Jira for what to fix. You're also likely to understand how to fix it without having to come up to speed, since you're already working in that code.
You are describing policy issues with a technical solution. The solution to policy issues such as those is to make it policy to only use the solution at appropriate times.
If you only allows TODO after a discussion (e.g. TODO: We decided to forego implementing X at this time, but we may need it later, as per project lead Y).
It does not prevent prioritization or ownership, and there's nothing to prevent a corresponding entry in some management system (and indeed, you can put the ID from that system in the TODO).
That said, often there's things you want to signpost specifically for future developers (including yourself) which may not rise to the level of needing a ticket assigned or external tracking (or that may be complicated due to bureaucracy or or you measure goals being met). There are plenty of reasons to have an additional channel to signal information directly to a dev. Just don't make that instead off the official channels of communication without good cause.
In a couple of work environments, people would initial the TODO -- I'm trying to remember if Joyent is one of those companies. I liked this, because it was extra honesty about the craft and I could pick the person's brain if there were issues in that code. It would also seem to allow to get a TODO brain dump when someone is planning on leaving the company or assist in who to bring to the table for refactoring of a large component.
Tagging TODOs is really useful. I can always look at source control, but that's more effort than seeing a name or bug number. At Google our linters are actually configured to create errors for any TODO/FIXME that isn't immediately followed by a user id or bug number: e.g. TODO(12345) or TODO(myname). I thought it was a little annoying at first, but over time I've realized how much faster it is to have that additional context.
I think it's important to highlight that it's definitely about context rather than ownership when adding a name or bug number to a TODO comment.
"// TODO(dmi): update after moving to Java8" doesn't necessarily mean that it's _me_ that has to fix it, but that someone can come to me and say "Tell me more about this". This took me a while to learn/remember, but it's very helpful. The hardest part for me to keep in mind was that someone else's name on a TODO shouldn't mean I ignore it.
I recently finished writing my master's thesis on "the impact of self-admitted technical debt on software quality" [2], we use the same approach this article advocates to identify this type of technical debt, which we call "self-admitted technical debt" (SATD) [1].
We examined the impact of SATD on software quality for forty open-source projects. To measure this, we took into account three criteria commonly associated with quality: (i) on the file level, the relationship between defects and SATD; (ii) on the change level, the potential of SATD to introduce future defects and (iii) the complexity SATD changes impose on the system. The results of our study indicate that: (i) SATD and defects exhibit no correlation at the file level, (ii) SATD changes make the system more susceptible to future defects than non-SATD changes do and (iii) SATD changes are more difficult to perform on the system. [2] (an abbreviated version [3])
There are more patterns to identify technical debt than "TODO, FIXME or XXX". You can find the rest of the patterns here [1].
It is very interesting to see developers confessing their workarounds and hacks through source code comments, as it can alert later contributors to the technical debt induced.
This may be a technique to support tracking of technical debt IN your source code IFF it can be attributed to a specific place. Some of the more vexing debt is across the code, in the systems around the system being build or in the tool chain and needs other types of tracking.
Can't speak for the author, but to me "technical debt" is needed fixes that don't quite fit in a bug report because they don't fix any bug, and they don't deserve a feature request because they don't add features. Therefore your taskmaster/overlord/scrum-master has no place to put them and in fact you'll have trouble convincing anyone, especially non-coders, that it needs to be done at all. So, track it in the code, since devs are the target audience and since "in the code" is where you'll be the next time you find yourself having to deal with "that kludge" again.
There are also some organizations where the ticket backlog management... Well, old bug reports are sometimes deleted because "anything before this date probably is obsolete."
That's why sometimes the code is a better spot to leave a hint for the next poor sap -- or yourself -- who stumbles across the thing again.
Where I work, they fall under the heading of "chores", for which the usual definition given is "something that will improve future velocity".
Engineering owns these and gets to prioritise them as necessary. It's usually done with an eye to the current backlog of stories and bugs that product has prioritised.
Sometimes chores get done opportunistically. You have a time gap, you grab a short chore and do it.
Or you might spin one out of a story as a kind of marker of known tech debt.
Sometimes engineering sees a heavy piece of tech debt that is a millstone and just goes ahead with it. Usually this ties up a track of work that becomes unavailable for product work, sometimes for weeks.
At an organisation I recently worked for we did both.
Technical debt tickets were created in the issue tracker. The ticket offers plenty of space to detail the technical reasons for implementing potentially suboptimal code in the first place (a justification for the introduction of technical debt), a general outline of the approach to resolving the debt and to list out business justifications for resolving the debt.
A TODO comment referencing the ticket was added to the code. This reduced comment bloat and allowed a developer to easily find the relevant source from a ticket and vice versa.
Technical debt issues were added to each sprint/development cycle by product managers with developer input during planning sessions.
This process also had the benefit of letting developers fill in small amounts of possible development downtime. If you know you have to leave the office in 30 mins (a dentist appointment for example that you can't miss), you may be uninclined to start work on a large feature. Picking up almost any small tech debt ticket turns that time into something more productive than nothing.
You don't want to create 15 detailed issues each time you refactor 5-15 hour old project or feature branch. Merging these into trunk/master is obviously less meaningful. // FIXME bad wording?
Todos (and fixme, xxx) are very useful as review or editing anchors.
I agree. For me, TODO-style comments are very useful for stuff I'm currently working on, as a short term aid. Usually I wouldn't be committing them, except for things like short-lived commits on a working branch that will be rebased out later.
For example, if I'm adding a substantial new feature and it will affect the code in a few different places, I'll often go through first and leave easily searchable markers at the exact locations where I expect to make changes. Then I can do a quick comparison between where I'd expect to need changes given the design and where I've found to make them to ensure they match up before I start changing anything, and then I can move quickly through all of the required changes without losing focus.
It really depends. My usual routine for brand new projects is to init RCS/tracking only once something meaningful emerges, and that time may vary. For "research" projects I simply don't do that, because initial refactoring history has no value and project is copy-and-throwaway anyway. Marker comments may be the only tracking method there. Once code is moved into real workdir, all todos are subject to regular issue tracking.
I like the way the Golang team handled the introduction of Contexts. Adding them required a lot of re-thinking, and so they added a Context.TODO() method which returned a context stub essentially.
Something similar could be used with todo comments in general, e.g. in your favorite language something along the lines of:
import todo
todo.add("Fix this later")
Which would keep track of those and you can somehow automate reporting, various restrictions and what not.
I've been taught to keep these out of production code. If your code fails in a way that gets you in a lawsuit you won't want to be explaining what that "TODO: looks like a xxx here" means to the judge.
Maybe if you're coding the algorithm for when to deploy airbags or something similarly life-protecting - but many of us are just coding todo list web sites and the next social media app.
As much of a rule-follower as I am... I think that if I always had to code for the eventual lawsuit, I'd quit coding.
I have been doing this for years. I find it helpful when going to refactor a part of the app that has problems. I then go look in the code and see TODO comments I added a while ago. Then I am 100% sure I really should fix that up. Yes they can get stale but usually they tend to be helpful.
I really like reading todos written by other devs to see where a feature was left incomplete. It's so much easier to see it right in the code rather than lost in a ticketing system.
I was weirded out by this line: "Some tools, IDEs in particular, tend to assume that you should fix all your TODOs before you commit anything."
Holy crap that's fragile!
I'm still looking for the value add of an IDE. I'm not negative toward them (I know many many people use them and get a lot of value out of them) but I personally have never found one that was easier than simply writing and compiling code. Could be my use cases (the kind of code I write/projects I do).
Ditto until relatively recently. Vim, Emacs, jEdit, Notepad++ until about four years ago when I tried IntelliJ IDEA. Never looked back. It was also an eye opener about the limits of tool support in loosely typed languages.
I have a colleague using IDEA for the part of our project that's in Java. There's a continuous stream of curses coming from his desk and he's been programming in Java since it was first announced by Sun.
Part of the problem I think is taking your hands of the keyboard to manipulate the mouse.
A lot of hate for TODO/FIXME in the comments... We've been using them successfully in open source for decades. I would never rely on them between releases, but during active development of a single release they are handy.
A single line is not enough to explain work needed to be done or getting said work done, but it can be enough to explain existing work, sometimes.
One way I thought of doing this would be to just have every commit tagged with some subjective score given by the committer (in commit message), probably just 1,2,3 to avoid too much weird subjectivity of a x/10 ranking, that gives how much the user subjectively thinks a commit is janky. then you will get a map of source code quality over time
No, this will take into account any changes in spacing which are legit changes that sometimes need to be made but have no effect on the logic of the commented routine.
1. If you are going to write TODO, write TODO(paul) or similar, so that you easily know the originator.
2. Unless the dev team is very small, most TODOs belong in your issue tracking system. That's where they can be enumerated, described, discussed, prioritized, assigned, etc.
I see TODO's in production code as only somewhat better than commenting out 'almost working' code.
It helps me understand the original intent of the developer, but I don't trust that it's actually the right thing to do, and mostly shouldn't be there.
Lately I've been finding a thorough test suite to be better at documenting code than comments. But I have to chuckle at "self documenting" every time I hear it.
A good way to minimize technical debt is to block PRs that have TODOs until the author completes them, therefore eliminating the technical debt they would have otherwise introduced.
Although I wonder how much self-censorship that encourages. Whether or not to put a TODO in your code is a judgement call. If you tell some developers that admitting to a TODO means that they can't submit, they might not admit to them as often.
It's a bit case-by-case, but I think I'd rather encourage contributors to admit to the lacks in their code and accept them - but get them to commit to follow ups that will fix the problems.
This is likely to lead to developers just leaving out the TODOs instead of doing the work. Especially for work that isn't needed now but should be done at some point in the future.