5.1 KiB
Comments and Formatting — Clean Code Chapters 4 and 5
Source: Robert C. Martin, Clean Code. Summaries: Vivek Khatri Ch. 4, Vivek Khatri Ch. 5, LinkedIn summary of Ch. 4.
Contents
- Comments
- C1. Acceptable comments
- C2. Banned comments
- C3. Docstring discipline
- Formatting
- Fmt1. Vertical openness separates concepts
- Fmt2. Vertical density implies association
- Fmt3. Vertical distance
- Fmt4. Horizontal density
- Fmt5. Match the file you're editing
- Self-check for comments and formatting
Comments
The foundational rule: "Don't comment bad code — rewrite it." Comments are failures to express intent in code. Every comment is a candidate for rename or extract.
C1. Acceptable comments
A short list of comments that earn their keep:
- Legal headers — license boilerplate, copyright.
- Intent — explaining why a decision was made when the choice is non-obvious. Example:
// Use exponential backoff to avoid hammering the rate limiter during retries. - Warnings of consequences —
// This function is called during transaction commit; do not raise. - TODOs — sparingly, with a tracking ticket reference.
// TODO(JIRA-1234): switch to streaming once API supports it. - Public API documentation — docstrings that document contract (preconditions, postconditions, raises), not body.
- Amplification — calling attention to something non-obvious.
# The+ 1accounts for the inclusive end of the range; see RFC §3.2.
C2. Banned comments
Delete on sight:
- Restating-code comments.
// increment counter by oneabovecounter += 1. The comment adds zero signal and creates two things to maintain. - Noise comments.
# default constructor,# getter,# returns the day of month. - Banner comments.
# ====== USER FUNCTIONS ======. Use a class or module split instead. - Closing-brace comments.
} // end of for loop. If you need this to follow the flow, the function is too long. - Attributions and journal comments.
# Updated by Bob on 2023-04-01 to fix bug #42. Version control records this. - Commented-out code. Delete it. If you need it back, git has it. Commented blocks are toxic — readers don't know whether to trust them.
Step 1/Step 2scaffolding. Common LLM artifact. Each step should be a function call with a name; the names provide the structure.
C3. Docstring discipline
A documentation comment that paraphrases the function signature is noise:
Bad:
add(a, b)
// Adds a and b and returns the result.
return a + b
Good:
add(a, b)
return a + b
A documentation comment earns its keep when it documents contract: what may be passed, what may be returned, what errors are raised, and any non-obvious side effects.
Good:
// Charge a payment source.
// Returns: charge identifier.
// Raises: CardDeclined for decline failures; PaymentProviderError otherwise.
// Side effect: writes an audit record on success.
charge(paymentSourceId, amountCents)
Formatting
Fmt1. Vertical openness separates concepts
Blank lines between concepts. No blank lines inside a tightly-coupled block. The eye uses blank lines as boundaries.
Fmt2. Vertical density implies association
Code that belongs together should sit together. Variable declared 30 lines from its use is a smell.
Fmt3. Vertical distance
- Variables declared close to use. Not at the top of the function "C-style."
- Caller above callee. Top-down reading: high-level function first, then the helpers it calls. The step-down rule (naming-and-functions.md F4).
- Conceptually related functions adjacent. If
parse_invoiceandvalidate_invoiceare siblings, put them next to each other, not on opposite ends of the file.
Fmt4. Horizontal density
- Spaces around assignment and comparison operators:
x = 1,if x == 1. - No space between function name and parenthesis:
f(x)notf (x). - Line length: 80 traditional, ≤100–120 acceptable. Beyond 120 is careless.
Fmt5. Match the file you're editing
The most common cross-cutting violation: introducing a new style in a file that already had one. If the file uses snake_case, do not introduce camelCase. If it uses double quotes, do not introduce single quotes. If it sorts imports alphabetically, do not append at the bottom. If the project already has an HTTP client, database wrapper, or logging helper, reuse it instead of introducing another one.
Team rules override personal preference. Read the file, then write.
Self-check for comments and formatting
Before you ship code:
- Walk every comment you added. For each, ask: does it explain why? If it explains what, delete it.
- Walk every documentation comment you added. Is it paraphrasing the signature? Delete the paraphrase; keep only contract documentation.
- Any commented-out code? Delete it.
- Any
Step 1,Step 2,First, ..., orThen, ...scaffolding comments? Delete. - Are variables declared near their use, not at the top?
- Does the casing, quoting, and import order match the file's existing style?