To Comment or Not To Comment

Navigating the Art and Science of Code Comments

Indrajeet Patil

RenΓ© Magritte's 'The Treachery of Images' painting showing a pipe with text 'Ceci n'est pas une pipe' (This is not a pipe)

What You’ll Learn

  • Why commenting matters for code quality and maintainability
  • When to comment and when not to comment
  • Common commenting pitfalls to avoid
  • Practical strategies for writing clear, helpful, and meaningful comments†
  • Tools and techniques for better documentation practices


🎯 Goal

Transform commenting from an afterthought into a deliberate practice.

β€œCode tells you how; comments tell you why.”

- Jeff Atwood

Why Comments Matter

Good comments act as guideposts for navigating complex code.

Why It’s Challenging

Multiple pressures during development make thoughtful commenting difficult.

flowchart TD
    A[Deadline Pressure] --> D[High Cognitive Load]
    B[Complex Problem Solving] --> D
    C[Implementation Focus] --> D

    D --> E[Commenting Shortcuts]

    E --> F[No Comments]
    E --> G[Obvious Comments]

    H[Comment Rot] --> I[Outdated Comments]

    style A fill:#f8f9fa,color:#000
    style B fill:#f8f9fa,color:#000
    style C fill:#f8f9fa,color:#000
    style D fill:#fff3e0,color:#000
    style E fill:#ffebee,color:#000
    style F fill:#ffcdd2,color:#000
    style G fill:#ffcdd2,color:#000
    style H fill:#ef9a9a,color:#000
    style I fill:#ffcdd2,color:#000

N.B. Documentation vs. Comments

def apply_discount(order_total, customer_tier, is_bulk_order):
    """Apply tiered discount based on customer and order type.

    Args:
        order_total: Pre-discount order amount
        customer_tier: 'bronze', 'silver', 'gold', 'platinum'
        is_bulk_order: True if order quantity > 100 items

    Returns:
        Final discounted amount
    """
    # Base discount rates per tier (as of Q4 2024 policy)
    tier_discounts = {
        'bronze': 0.02, 'silver': 0.05,
        'gold': 0.10, 'platinum': 0.15
    }

    base_discount = tier_discounts.get(customer_tier, 0)

    # Bulk orders get additional 5% off per marketing policy
    # but total discount cannot exceed 25% per finance rules
    if is_bulk_order:
        total_discount = min(base_discount + 0.05, 0.25)
    else:
        total_discount = base_discount

    return order_total * (1 - total_discount)

Documentation

  • API contract
  • How to use the function
  • Parameters & returns
  • For function users

Comments

  • Implementation details
  • Why it works this way
  • Business rules & context
  • For code maintainers

Documentation for public interface, comments for private implementation.

What Not to Comment

Every comment distracts from reading codeβ€”make sure it’s worth the interruption.

Don’t use crutch comments

Crutch comments compensate for unclear codeβ€”fix the code instead.

❌ Comment compensates for bad naming

# Check if user can access premium features
def chk(u):
    return u.tier == 'gold' or u.tier == 'platinum'

βœ… Clear naming needs no comment

def has_premium_access(user):
    return user.tier in ['gold', 'platinum']

❌ Comment explains complex logic

# Apply 10% discount if total > 100,
# or 5% if > 50, but cap at 20
discount = min(0.10 if total > 100 else
              (0.05 if total > 50 else 0), 0.20)
final = total * (1 - discount)

βœ… Simplify logic, eliminate comment

def calculate_discount(total):
    if total > 100:
        return min(0.10, 0.20)
    elif total > 50:
        return min(0.05, 0.20)
    return 0

final = total * (1 - calculate_discount(total))

\[ \text{good code} > \text{bad code} + \text{comments} \]

Don’t state the obvious

❌ Bad

# increment counter
counter += 1

βœ… Good

# Reset retry count after successful connection
counter = 0

Don’t repeat variable names

❌ Bad

# user name variable
user_name = "john"

βœ… Good

# Store normalised username for database
user_name = normalize(input)

Don’t explain language syntax

❌ Bad

# if statement checks condition
if user.is_active():
    process(user)

βœ… Good

# Only process active users per business rule
if user.is_active():
    process(user)

Don’t write misleading comments

❌ Bad

# Calculate average
return median(values)

βœ… Good

# Calculate median for anomaly detection
return median(values)

Don’t keep outdated comments

❌ Bad

# TODO: fix this hack (3 years old)
legacy_workaround()

βœ… Good

# Use new API endpoint per v3.0 migration
refactored_solution()

Don’t use unclear references

❌ Bad

# See the function above
apply_discount()

βœ… Good

# Rate logic in pricing.calculate_discount()
apply_discount()

Don’t retain dead code as comments

❌ Bad

# old_function()
# legacy_code = True
new_function()

βœ… Good

new_function()

Don’t write temporary comments

❌ Bad

# FIXME: broken, fix later
# TODO: optimize this
hacky_solution()

βœ… Good

# Current: linear scan (tracked in #1234)
# Future: switch to hash lookup when ready
proper_solution()

Don’t confuse docs with comments

❌ Bad

"""Implementation uses binary search
for O(log n) complexity"""

βœ… Good

"""Find user by ID."""
# Use binary search for O(log n) lookup

Don’t use profanity or humour

❌ Bad

# This is a clusterfuck
process_legacy_data()

βœ… Good

# Complex legacy integration, needs refactoring
process_legacy_data()

Don’t use inside jokes

❌ Bad

# Here be dragons
process_transaction()

βœ… Good

# Handles concurrent writes with optimistic locking
process_transaction()

Don’t vent frustrations

❌ Bad

# Stupid requirement from management
validate_input()

βœ… Good

# Business requirement: process within 24h
validate_input()

What to Comment

Follow this principle instead of memorizing rules:

Good comments explain the why and provide essential context.

Explain the Why

❌ Comments describe β€˜what’

# Set timeout to 30
timeout = 30

# Connect to database
db.connect(retry=True)

# Loop through users
for user in users:
    process(user)

βœ… Comments explain β€˜why’

# Timeout increased to handle slow network
# conditions in international deployments
timeout = 30

# Retry enabled to handle observed
# transient network failures
db.connect(retry=True)

# Process in batches to avoid memory issues
for user in users:
    process(user)

Tip

Good comments explain business logic, design decisions, and non-obvious requirements.

Explain Constraints and Assumptions

❌ Vague

# as per spec
if len(data) == 0:
    return None

βœ… Specific

# Return None for empty datasets per
# API specification v2.1 section 4.3
if len(data) == 0:
    return None

❌ Too generic

# handle the data
data = clean_input(raw_data)
result = process(data)

βœ… Provides context

# Input must be UTF-8 encoded strings
# Assumes data fits in memory (<1GB)
data = clean_input(raw_data)
result = process(data)

Tip

Precise comments save debugging time and prevent misuse of APIs.

Clarify Complex Conditionals

❌ Unclear complex condition

if (user.age < 18 and
    not user.has_guardian_consent and
    user.account_type != 'premium'):
    restrict_access = True

βœ… Clear business rule

# Minors need guardian consent unless premium
if (user.age < 18 and
    not user.has_guardian_consent and
    user.account_type != 'premium'):
    restrict_access = True

❌ Cryptic condition

if not (status == 'active' and balance > 0):
    return False

βœ… Explains business logic

# Account must be active with positive balance
# to be eligible for new transactions
if not (status == 'active' and balance > 0):
    return False

Tip

Complex conditionals should explain the business rule or decision criteria.

Document Non-Obvious Algorithms

❌ No algorithm explanation

def find_median(arr):
    arr.sort()
    n = len(arr)
    if n % 2:
        result = arr[n//2]
    else:
        result = (arr[n//2-1] + arr[n//2]) / 2
    return result

βœ… Algorithm details explained

def find_median(arr):
    # Use sort-based approach:
    # O(n log n) time, modifies input in-place
    arr.sort()
    n = len(arr)
    # odd length: middle element
    if n % 2:
        result = arr[n//2]
    # even length: average of two middle elements
    else:
        result = (arr[n//2-1] + arr[n//2]) / 2
    return result

Tip

Algorithm comments should explain the approach and trade-offs.

Tools & Techniques

Tool Limitations

What tools CAN do:

  • Check comment formatting and style
  • Flag TODO/FIXME comments
  • Detect missing documentation
  • Generate basic API documentation

What they CANNOT do:

  • Understand if comments explain the β€œwhy”
  • Assess comment usefulness and clarity
  • Determine if business context is missing
  • Evaluate comment accuracy after code changes
  • Judge whether comments add value

The fundamental limitation

Tools can enforce format but not value. Good commenting requires human judgment about what information is helpful.

AI as an Ally

Why AI tools can help:

  • Analyze code complexity and suggest documentation
  • Identify business logic that needs explanation
  • Check comment clarity and helpfulness
  • Generate initial documentation drafts

flowchart TD
    H[Human] --> S[Quality Comments]
    A[AI] --> S[Quality Comments]
    H -.->|Collaborates| A
    A -.->|Feedback| H

    style H fill:#e3f2fd
    style A fill:#f3e5f5
    style S fill:#e8f5e8

Symbiotic Commenting

Write initial comments yourself. Then, ask AI tools to identify gaps, suggest improvements, or validate clarity.

Cross-LLM Review

Use a different LLM to evaluate comments than the one used to write the code.

Code Review Benefits

flowchart TD
    A[Code Review] --> B[Lower Cognitive Load]
    B --> C[Fresh Perspective]
    B --> D[Focus on Clarity]

    C --> E[Question Assumptions]
    C --> F[Spot Missing Context]
    C --> O[Find Outdated Comments]
    D --> G[Evaluate Intent]
    D --> H[Assess Usefulness]

    E --> I[Better Comments]
    F --> I
    G --> I
    H --> I
    O --> I

    style A fill:#e3f2fd,color:#000
    style B fill:#f3e5f5,color:#000
    style C fill:#f8f9fa,color:#000
    style D fill:#f8f9fa,color:#000
    style E fill:#fff3e0,color:#000
    style F fill:#fff3e0,color:#000
    style G fill:#fff3e0,color:#000
    style H fill:#fff3e0,color:#000
    style O fill:#fff3e0,color:#000
    style I fill:#e8f5e8,color:#000

Code review transforms commenting from reactive to deliberate!

The Benefits

β€œPrograms must be written for people to read, and only incidentally for machines to execute.” - Harold Abelson

Context and Understanding

  • Well-written comments make complex code comprehensible.
  • Writing thoughtful comments forces you to articulate your reasoning and design decisions, improving code quality.
  • Explaining your code in comments clarifies your own understanding and reveals potential issues.
  • Good comments preserve business knowledge and domain expertise for future developers.
  • Strategic commenting reduces onboarding time for new team members.
  • Consistent commenting practices reduce cognitive overload and make maintenance safer.

Worth Mastering

Invest time in thoughtful comments earlyβ€”they pay dividends by preserving knowledge and intent.

The more you practice, the better you’ll get at knowing when and how to comment!

Thank You

And Happy Commenting! 😊

For more

If you are interested in good programming and software development practices, check out my other slide decks.

Find me at…

LinkedIn

GitHub

Website

E-mail