The other day while listening to edge cases, i was tickled to hear wolf talk about comments and how, as he's aged, he prefers really only two flavors of comments, API Comments/Documentation and here be dragons comments. But sadly, he didn't mention the kind of comments i'm going to talk about here.

To begin, he cites this gem from wikipedia:

Due to time restrictions or enthusiastic programmers who want immediate results for their code, commenting of code often takes a back seat.

At work, we have a slogan "shipping beats perfection"1 and it is much of the rationale for this other kind of comment, which i will call the unblocking comment.

the unblocking comment

The practice, introduced to us via craig silverstein2, (and to be clear, khan academy is not unique here) is to leave comments for the things you recognize are probably out of immediate scope and that you aren't able to get to right now so that you can get on with your original commit (i.e. unblocking yourself).

let me show you a 'for instance' from my super hacky tumblr editor package:

# TODO(marcos): what if this also fails?
if more_info['meta']['status'] == 200:
    post = more_info['response']['posts'][0]
    # TODO(marcos): maybe check a pref for this
    webbrowser.open(post['post_url'])

the two TODO(marcos) comments map to things that i might, at some point get to eventually, but that aren't truly 'blocking' or 'stopships' or whatever. They're basically baby yaks that if i'm not careful, might develop into full grown yaks3 demanding my attention and shears.

or more recently, this past week, while playing with Framer:

// TODO(marcos): use cycle here
var collapsed = true
scrubBG.on(Events.Click, function(){

    if (collapsed) {
        // TODO(marcos): instead of just unclipping the layer
        // animate the text in separately

And, to be clear, the code works! Right now! it's just that if i ever want it to work better or if i return to it, i have already outlined a roadmap for myself (or others) on how to do that. The framer code is by definition a prototype, so let's be honest, who cares if i'm using cycle correctly, but my intuition to Do The Right Thing™4 is the sort of yak that might have wasted precious prototyping time.

These todos, in the context of both projects, are the software development equivalent of a "sweep" in gtd5. Which is to say, that in writing the todos, i've explained what i need to do (but i can't do right now), and by doing so, i've absolved myself of the guilt of doing it this very minute.

Allow me to repeat: by leaving the todo(), i communicate to others (or future-marcos) my understanding that the problem exists but that rather than investing time in writing possibly unneccessary code, i am moving on. In the present day, it gets me unstuck and moves me forward towards a working implementation that i can nit-pick later.

Again, i'm not promising work on the femtoyak right now, i'm not even committing to it in the future (as my tumblr comments have borne out)—i'm doing two things: publicly acknowledging the issue exists and punting it so that i can get on with my day. Why even put my name on it, you ask? If somebody does get around to it, they know exactly who to ask for more detail! I'm happy to help them!

Most of you are shouting at your monitor saying that this is like time-management 101, but it took my subconsciously creating these todo() comments to get me to truly internalize their real ultimate power.

The novelty here, the point where this ties back to the quote, is that this is actually the opposite of the problem outlined in the wikipedia article. In my vim to get towards a working solution, i'm leaving important implementation and polish related comments for myself (and others) so that i can address it better... but only once i have something that merits fixing.

Just to be clear, though, if you have actual bugs that merit tracking, you really should find a way to get to those in a way that's higher priority than these TODO()s which really are historic context-rich vignettes of the rabbit-holes you've avoided. By all means, continue logging assertions and running unit tests for your bits that need to remain stable!

But... i want to repeat the central 'point' here which is that comments don't have to take a backseat to getting things done. In fact, i hope i've shown that, comments can provide a relatively easy way to get you from "zero to working"6 while providing a legitimate roadmap for you to get to something sustainably developed in the future.

dealing with guilt

I've been trying to find a good way to end this essay, some sort of meditation on why something as mundane as a todo comment would even be necessary to write about. It took the span of a few weeks for the podcast gods to answer my call in the form of an episode of ATP, going full-circle.

The episode is interesting because it deals with deeper issues of obligation and guilt in software development and maintenance. It's a highly relatable episode for anyone that has participated in the open source ecosystem. In particular, it pairs well with this 100% insightful essay called Emotional Programming in Open Source by Armin Ronacher. You should definitely read it, but I'm going to pull a whole chunk of it here:

I found it quite hard this year to work on my own projects because the bug trackers were full of things I personally did not really care about. The things I wrote over the last few years all work so well for me, that I don't need to fix problems or add things. When there is something that needs fixing, I will work on it, but otherwise I don't necessarily get the motivation to work on it.

... the whole porting to Python 3 thing has killed so much motivation for working on my project for me. I cannot use Python 3 in practice and having to deal with issues I don't have myself is one of the most frustrating things.

He calls out an important distinction between bugs which are currently breaking a build and in-utero yaks which shouldn't be on your radar just yet. Todos, in contrast, aren't traditional 'bug' reports, they're opportunities; for refactoring, future architecture changes, performance optimizations, etc. Maybe they're nice to haves, maybe you discover they're actual bugs: time will tell.

The effect of writing and revisiting TODO()s is better understanding the dynamic between problems you have right now and issues that are actually non-issues. If a todo lingers for a while, it's probably not an issue you really have and certainly not one that's keeping your project from functioning in the short term. Maybe if you're bored you hit it up. Maybe a contributor decides to attack it.

But the problem that many of us have, is that we know what The Right Thing is but our time and priorities are at odds with that. Does that choice make us worse programmers? Should it hold us up from releasing a project? Would it be better if we just pulled our project? No to all. It's a calculus of writing code, our time available, obligation to our code's users and our own guilt. Those are challenging things to balance!

Developing software in the open is complicated even when when you're bootstrapping it in private. But it gets more difficult if making progress is fraught with guilt and obligation to some all-seeing Van Hœt. So many of these issues, these problems in casual development are complex issues of time management, guilt and obligation. Leaving todos can free you from worry and push you towards fixing issues you care about right now so you can start enjoying the software you make.

thanks

it wouldn't be a real thousand word internet blog post without an artisinal colophon, so thanks for the feedback and comments: @marcia_lee, @andy_matuschak, @kamens, @pgbovine, @dmnd_, and chrisklaiber and @dylanvee.

If you have any thoughts on this and have made it all this way, i'd love to hear from you. Feel free to send me an email.


  1. its background is this other phrase, bias towards action, which, to be honest, i don't think i'd heard until this past week. It is, however, an interesting cousin of the more contentious Worse is Better™[^wib]

  2. craig has been responsible for many fantastic process gems, so i feel very lucky to be able to crib this one from him almost entirely wholesale for my own internet fame and glory.

  3. , which see

  4. i'm pretty sure spike lee never thought his movie would ever be referenced so often in terms of software engineering discussions

  5. A sweep, briefly, is this nifty idea where in order to be able to prioritize all the task you possibly have, you put everything you can think that might be a task into a task list. By moving all those ideas out of your head and into a place you're likely to look at later, you allow your mind to only wander to tasks that are relevant now. gtd® is copyright DavidCo 2001.

  6. although philosophically aligned, this is not going to devolve into an essay about minimal/maximal viable products. phew.