A Commentary on Code Comments

If there’s one thing LLMs seem to love, it’s padding out code with unnecessary comments and docstrings.

This post may come across as an old-man-yells-at-cloud-style rant but it’s a trend I’ve noticed that in my eyes, is actively making codebases harder to read and maintain. Here’s why.

War and Peace

To me, code that’s easy to read and maintain is code that is self-documenting. By that I mean it’s well-structured, doesn’t try to do too much at once, and uses clear, descriptive names throughout (easier said than done, I know).

If your code is already well written and structured, adding comments and docstrings that re-state what your code is doing, what parameters methods take and/or return types is just noise. It’s unnecessary fluff that someone needs to scroll through to get to the line of code that they’re looking for.

If you feel you need comments to explain what your code is doing, that may be the first sign that it’s too convoluted or complex.

Arnold Schwarzenegger as the President in The Simpsons Movie saying 'I was elected to lead, not to read'
The Simpsons Movie (2007)

Liar Liar

The only constant in software engineering is change (so deep, join my cult). As you find bugs or add new features your actual code will change, because it has to.

Comments however, can easily be missed because they don’t do anything. It’s harder to spot when a comment should be updated because there’s no measurable impact. There’s generally no test suite that fails, and no screaming product manager if it isn’t updated in time.

This means that your comments and your code can often get out of sync. Your comments can end up lying to the reader about how your code actually behaves. Life as a software engineer is already hard, let’s not make it any harder than it has to be by lying to each other.

Taking Up Tokens

More comments also mean more text for an LLM to read through when it’s trying to understand your codebase. If you’re using one to help navigate existing code, then every comment it processes are tokens spent on noise rather than signal.

Ironically, the same tool that will happily generate fifty lines of docstrings is now also having to wade through those same fifty lines every time you ask it to make a change. If any of those comments are out of date, you’re only wasting tokens and feeding your model misinformation.

The Vibe(Code) Check

There’s something about an abundance of comments through code that just makes me trust it a bit less. This could be completely unwarranted, but when I see a pull request that’s riddled with what are clearly AI-generated comments, I’m immediately a bit more sceptical of it.

I think I feel a bit uneasy because it indicates that the author may not actually have read a lot of the code themselves. It gives off a sense of “ah, that’ll do”, a sense that someone hasn’t dotted all the i’s and crossed all the t’s.

Again, that may be completely unfair, but it’s something I can’t quite shake.

Why, Not What

There’s always exceptions, I’m not an out and out anti-comment zealot.

Comments are genuinely useful when they’re used to describe why a decision was made. This isn’t necessarily something that can be understood by reading the code alone.

When comments are used to explain a non-obvious reason behind implementation or some business logic then they do actually provide value, both to humans and to AI agents who need to get an understanding of the code.

For example, something like this could justify its place in a codebase:

# We deliberately don't retry on 429 here, the upstream rate limit resets
# monthly and retrying would just queue up failures for 30 days.
if response.status_code == 429:
    raise HardFailure()

Same Old Story

Of course, none of this is new or revolutionary territory. The argument against over-commenting has been made countless times before. What has changed is that LLMs have made it dramatically easier to generate noise at scale, and I think more and more people are starting to mistake that noise for thoroughness.

← All posts