SuperAPI AI Directory

self-documenting-code

Coding & development

View repository

Updated 10-16 01:19

About this skill

Self-Documenting Code

The test for any comment: does it say something at the same level of abstraction as the code next to it? If yes, it duplicates the code — refactor so the code says it, then delete the comment. If it operates at a different level — more precise (units, ranges, invariants) or more abstract (intent, contract, rationale) — it carries information code cannot, and it stays.

This is not "never comment." Ousterhout's A Philosophy of Software Design is the sharp counterpoint to comment-minimalism: "comments should describe things that aren't obvious from the code" — and for interfaces, plenty isn't. The skill is telling redundant comments from load-bearing ones.

Use this skill when

  • Writing or reviewing comments in a diff.
  • A comment seems needed to explain what a line or condition does.
  • Deciding whether to keep, delete, or rewrite an existing comment.
  • Refactoring dense logic that is hard to follow.
  • The user mentions comments, docstrings, self-documenting code, or readability.

Do not use this skill when

  • The user explicitly wants explanatory/teaching comments (tutorials, examples, learning codebases).
  • You'd delete a comment because it's inconvenient rather than redundant — a wrong comment gets fixed, not removed.

Refactor the "what" into the code

1. Name sub-expressions

A condition that needs a comment to decode can be rewritten to read like the comment:

# user can check out only if active, cart non-empty, not banned
if user.active and len(cart.items) > 0 and not user.banned: ...
has_items = len(cart.items) > 0
can_check_out = user.active and has_items and not user.banned
if can_check_out: ...

2. Extract a predicate

When the expression is large or reused, move it into a function whose name is the comment. The call site becomes plain intent, and the name — unlike the comment — can't be skipped by the next editor:

def can_check_out(user, cart):
    return user.active and len(cart.items) > 0 and not user.banned

3. Name magic values

if attempts > 5: ...          # why 5? (comment coming...)

MAX_LOGIN_ATTEMPTS = 5
if attempts > MAX_LOGIN_ATTEMPTS: ...

4. Let types state the fact

Nullability, ownership, allowed values, units — encode them in the type (Optional[User], an enum, Duration) and the checker keeps the claim honest. A comment asserting the same thing is unenforced. (Unit-bearing names: see naming-things.)

Why redundant comments are worse than none

Nothing checks a comment, so it drifts: the code changes, the comment doesn't, and now it actively misleads a reader who trusted it. A comment that repeats the adjacent code adds no information today and a maintenance liability forever. Ousterhout's first red flag is exactly this: comment repeats code — if a reader could write the comment from the code alone, delete it.

The comments code cannot replace

Two directions, per Ousterhout — both are legitimately about "what," and both survive the refactor-first test because no rewrite of the code can express them:

More precise than the code — pin down what the declaration leaves open:

retry_interval = 200   # what does 200 mean? is it fixed?

# Milliseconds. Doubles per attempt, capped at 30_000.
# Invariant: > 0; 0 would spin-loop the scheduler.
retry_interval_ms = 200

Units (when the type can't carry them), inclusive vs exclusive bounds, null semantics, ownership and lifetime, invariants, thread-safety expectations.

More abstract than the code — interface comments. A caller should understand what a function does, its parameters' meaning, side effects, and error behavior without reading its body. That summary is "what" documentation and it is required for any non-trivial public interface — this is where "comments only explain why" tips from principle into dogma. Keep interface comments free of implementation detail (Ousterhout's second red flag: implementation contaminating the interface); the docstring skills cover format.

Why-comments — always code-inexpressible:

  • Rationale and trade-offs: why this approach over the obvious one.
  • Performance oddities: code that looks wrong because it's tuned; say so, with the measurement.
  • Workarounds: "sidesteps bug X in library Y", with a link.
  • Cross-module obligations: "if you change this, update Z."

Comment-first as a design probe

When you do write an interface comment, try writing it before the body. If the comment comes out long, conditional, or hedged ("does X, but also Y if flag Z..."), the abstraction is muddy — fix the interface, not the wording. A clean one-sentence comment is evidence of a clean abstraction.

Decision table

Comment says... Verdict
What the next line visibly does Delete; refactor code if it wasn't visible
What a complex condition means Extract predicate / name sub-expressions
What a literal means Named constant
A fact a type could enforce Move into the type
Units, ranges, invariants, null/ownership semantics Keep — precision the code lacks
What a public function does for callers Keep — interface contract
Why this design / workaround / tuning Keep — rationale
Corrects a misleading name Fix the name, then delete

Quick checklist

  • Could a reader reconstruct this comment from the code alone? Delete it (refactor first if needed).
  • Commented condition or literal? Extract a predicate / name the constant.
  • Could a type enforce the claim? Encode it there.
  • Does the declaration leave units, bounds, or invariants open? Add the precision comment.
  • Public interface without a caller-level summary? Write one, free of implementation detail.
  • Hard to write that summary in a sentence? Suspect the abstraction, not the prose.

Related skills

  • naming-things — precise names are the primary mechanism for deleting "what" comments.
  • never-nesting — extracted, well-named functions document structure that comments would otherwise narrate.
  • python-google-docstrings / python-rest-docstrings — formats for the interface documentation this skill says to keep.