Bonus Course30 min read

The Fine Art of Commenting

"Local Developer Claims Code Is 'Self-Documenting'; Code Respectfully Disagrees"

Dear Marilyn: My colleague says "good code doesn't need comments." I say that's what people say right before they quit and leave us with 50,000 lines of mystery. Who's right?

— Commenting Crusader in Cleveland

Illustration of a code graveyard where uncommented code goes to die - tombstones with cryptic variable names and developers mourning lost knowledge

Dear Crusader: Your colleague is half right—in the same way that saying "good drivers don't need seatbelts" is half right. Yes, good code should be readable. No, that doesn't mean you shouldn't also explain why it exists.

The truth is that code tells you what is happening. Comments tell you why it's happening. These are different questions, and both deserve answers. What follows is a guide to commenting that will save your future self—and your unfortunate successors—countless hours of archaeological excavation.

The Case Against NOT Commenting

"Programmer's Hubris Leads to 6-Month Delay as Team Attempts to Understand 'Obvious' Algorithm"

Dear Marilyn: I understand my code perfectly. Why should I waste time writing comments for myself?

— Confident Coder in Chicago

Dear Confident: Do you also remember what you had for lunch three Tuesdays ago? The human brain has a remarkable capacity for forgetting things it once knew intimately. In six months, your "perfectly clear" code will look like ancient hieroglyphics—and you'll be the archaeologist trying to decode your own tomb.

The Three Excuses (And Why They're Wrong)

Excuse #1: "I Can Understand My Code"

Reality: You can understand it now. In a year, after working on twelve other projects, you will stare at it like a stranger.

Also: You are not the only person who will ever read this code. Unless you plan to maintain it forever (you don't), someone else will inherit your masterpiece.

Excuse #2: "I Don't Have Time"

Reality: Every minute "saved" by not commenting will cost you ten minutes later when debugging. This is not speculation—it is mathematical certainty.

The Truth: If you have time to write the code, you have time to explain it. The two activities should be inseparable.

Excuse #3: "Good Code Is Self-Documenting"

Reality: Good code tells you WHAT it does. Comments tell you WHY it does it, WHEN it was written, and WHO to blame.

Example: x = x + 1 is self-documenting. But WHY are we incrementing x? Is it a counter? An index? A workaround for a bug in a third-party library? The code cannot tell you this.

Exhibit A: The Perl Horror Show

Consider this real code implementing the Solitaire encryption algorithm:

#!/usr/bin/perl -s
$f=$d?-1:1;$D=pack('C*',33..86);$p=shift;
$p=~y/a-z/A-Z/;$U='$D=~s/(.*)U$/U$1/;
$D=~s/U(.)/$1U/;';($V=$U)=~s/U/V/g;
$p=~s/[A-Z]/$k=ord($&)-64,&e/eg;$k=0;

Can you understand what this does? Neither can anyone else. Now imagine maintaining it.

The same algorithm with comments is perfectly comprehensible. Comments transform "job security through obscurity" into "code that humans can actually work with."

Quick Check

Why is 'good code is self-documenting' an incomplete philosophy?

The Three Types of Comments

"Developer Discovers Comments Have Categories; Mind Blown"

Illustration of a 1950s storyteller at a campfire, with three types of stories represented: Documentary (a passport), Functional (a blueprint), and Clarifying (a lightbulb)

Not all comments are created equal. Understanding the different purposes of comments will help you write the right kind at the right time.

1. Documentary Comments

The "passport" of your code. These comments document the file's identity, history, and purpose.

/**
 * File: CustomerService.cs
 * Author: Jane Developer
 * Created: 2024-01-15
 * Last Modified: 2024-03-22
 * 
 * Purpose: Handles all customer-related 
 * business logic including registration,
 * authentication, and profile management.
 * 
 * Dependencies: Database, EmailService
 * 
 * Change History:
 * - 2024-03-22: Added email verification
 * - 2024-02-10: Fixed timezone bug
 */

Include: Filename, author, dates, purpose, dependencies, change history

2. Functional Comments

The "to-do list" of your code. These mark work in progress, known issues, and areas needing attention.

// TODO: Implement caching for performance

// FIXME: This breaks with Unicode input

// HACK: Workaround for vendor bug #1234

// XXX: Needs security review before release

// DEBUG: Remove before production

Pro tip: Most IDEs can search for these markers. Use them consistently.

3. Explanatory Comments

The "why" of your code. These explain reasoning, business logic, and non-obvious decisions.

// We use a 30-second timeout because the 
// payment gateway occasionally takes 25+ 
// seconds during peak hours. See incident 
// report INC-2024-0142 for details.
var timeout = TimeSpan.FromSeconds(30);

// Intentionally using >= instead of > here.
// Business rule: orders of exactly $100 
// qualify for free shipping (per PM decision
// in meeting 2024-02-15).
if (orderTotal >= 100) {
    ApplyFreeShipping();
}

Rule of thumb: If you had to think about it, write a comment.

Quick Check

You discover a bug that you can't fix right now due to time constraints. Which comment marker should you use?

Comment Style Guidelines

"Area Developer's Comments Longer Than Code; Colleagues Stage Intervention"

Illustration of a museum of commenting styles - exhibits showing 'The Over-Commenter' with walls of text, 'The Silent Type' with blank spaces, and 'The Goldilocks Zone' with just-right comments

Dear Marilyn: How much commenting is too much? My colleague writes a paragraph for every line of code. I write nothing. Surely there's a middle ground?

— Seeking Balance in San Francisco

Dear Seeking: The golden rule is this: comments should not exceed the length of the code they explain by too much. If they do, it's a sign the code itself is too complicated and should be refactored.

The Good, The Bad, and The Ugly

Good: Explains the "Why"

// Retry up to 3 times because the API 
// occasionally returns 503 during deployments
for (int i = 0; i < 3; i++) {
    var result = await api.Call();
    if (result.Success) break;
    await Task.Delay(1000);
}

Bad: States the Obvious

// Increment i by 1
i++;

// Check if user is null
if (user == null) {
    // Return null
    return null;
}

These comments add no value. The code already says exactly what they say.

Ugly: Lies

// Calculate the user's age
var discount = price * 0.15;

A wrong comment is worse than no comment. When code changes, update the comments!

Comment Formatting Best Practices

PracticeExampleWhy
Use complete sentences// This validates the input format.Clarity and professionalism
Start with capital letter// Calculate tax after discountConsistency and readability
Match indentation // Comment at same level as codeVisual association with code
Keep line length reasonable// Max ~80 characters per lineReadability without scrolling
Update when code changes// [Updated 2024-03-22]Prevent misleading information

Quick Check

Which of these comments provides the most value?

XML Documentation Comments

"Developer Discovers Triple-Slash Comments; Suddenly Looks Like a Professional"

Before and after illustration showing code transformation from amateur to professional with XML documentation - left side shows messy undocumented code, right side shows pristine documented API

In C# and .NET, XML documentation comments are special comments that can be automatically extracted to generate documentation. They're the difference between "some code I wrote" and "a professional API that others can actually use."

Essential XML Tags

/// <summary>
/// Calculates the total price including tax and discounts.
/// </summary>
/// <param name="basePrice">The original price before modifications</param>
/// <param name="taxRate">Tax rate as a decimal (e.g., 0.08 for 8%)</param>
/// <param name="discountCode">Optional discount code to apply</param>
/// <returns>The final calculated price</returns>
/// <exception cref="ArgumentException">
/// Thrown when basePrice is negative
/// </exception>
/// <example>
/// <code>
/// var total = CalculateTotal(100.00m, 0.08m, "SAVE10");
/// // Returns 97.20 (100 - 10% + 8% tax)
/// </code>
/// </example>
/// <remarks>
/// Discount is applied before tax calculation.
/// </remarks>
public decimal CalculateTotal(
    decimal basePrice, 
    decimal taxRate, 
    string discountCode = null)
{
    // Implementation
}

Common XML Tags Reference

<summary>

Brief description of the member

<param>

Describes a method parameter

<returns>

Describes the return value

<exception>

Documents possible exceptions

<example>

Shows usage examples

<remarks>

Additional information

<see cref="...">

Cross-reference to other members

<code>

Inline code formatting

Quick Check

What is the primary benefit of using XML documentation comments?

Course Summary

  • Comments are essential: Code shows WHAT, comments explain WHY.
  • Three types: Documentary (identity), Functional (TODO/FIXME), Explanatory (reasoning).
  • Quality over quantity: Don't state the obvious; explain the non-obvious.
  • Keep them updated: A wrong comment is worse than no comment.
  • Use XML docs: For public APIs, use /// comments for auto-generated documentation.

Download Cheat Sheet

When to comment, XML documentation, comment types, and maintenance tips