"FIXME" Doesn't Always Mean "Fix Me"

If you browse through the Swift (or LLVM) codebase for a while, you’ll see a comment like this:

// FIXME: Dependencies should be de-duplicated at serialization time,
// not now.

or this:

// FIXME: This is a hack. What we really want is to have substituted the
// base type into the declaration reference, so that we can compare the
// actual types to which two type declarations resolve. If those types are
// equivalent, then it doesn't matter which declaration is chosen.

or this:

// FIXME: This is inefficient.

And you might be wondering if anyone is tracking all of these things that supposedly need fixing. Is there a JIRA for each one? No, doesn’t seem to be…

The answer is that “FIXME” doesn’t really mean “this code needs fixing”, at least not in Swift and LLVM. It means “this code isn’t as good as it should be”.

  • Maybe it’s using a slow algorithm, like a linear search through thousands of elements instead of a hashtable or binary search.
  • Maybe it doesn’t handle some inputs that are unusual but not impossible.
  • Maybe the code’s behavior is fine, but it’s really hard to understand and could benefit from some refactoring.

…or one of many other reasons why code might not be as good as it should be.

There’s an interesting consequence of this slightly different definition, though. Sure, the code isn’t as good as it should be, but that doesn’t mean you should put effort into improving it, at least not right now. Why? Well, if the fix was easy, the original author probably would have done it.1 That means that if you are trying to “fix” the code, it might end up being a non-trivial change, which means a non-trivial amount of your time writing and debugging and testing. Your efforts may be better spent elsewhere, where something is actively causing a problem. (Perhaps a starter bug…)

So FIXME comments tend to stick around for a long time. That’s not automatically a problem. It just means that whatever deficiencies the original code had, they weren’t so bad that someone had to rewrite them. And if someone ever does come across a problem with the code, there’s a reasonable chance it’s related to whatever was called out in the FIXME. So that’s what it is: a note to future maintainers of the code if a problem does come up.

P.S. That said, there are definitely some FIXMEs that probably would be easy to fix, including some that may not have been easy to fix in the past but would be now. This was more a point about not assuming that they’re easy to fix, or that they automatically indicate poor health in the codebase, or that they should all be tracked in a bug tracker.

P.P.S. Note that there’s one case where “FIXME” should not be used, which is “this code looks like it should be better, but there’s a reason why it’s the way it is”. Maybe you can’t use a hashtable because the elements don’t hash well. Maybe the unusual inputs are handled by the caller instead (add an assertion!). Maybe the obvious refactoring would violate library layering, making the project harder to build. In these cases, the code still deserves a comment, but instead of “FIXME” I’d go with a simple “Note”.

  1. There are exceptions, usually when the original author of the code was working under time pressure, or was trying to make as small a change as possible so as not to disrupt other parts of the project. But that’s not the common case. ↩︎