Comment Your &*☠# Code – The Costs Of Comments – Why Everybody Hates Comments



Comment Your &*☠# Code – The Costs Of Comments – Why Everybody Hates Comments

0 0


talk-comment-your-code


On Github CodeFX-org / talk-comment-your-code

Comment Your &*☠# Code

The Axiom

Comments are always failures.

(Some guy with a book.)

He’s wrong!

Self Documenting Code

I don’t care about your code!

I want to know what happens when I use it!

  • pre- & postconditions

  • what return value can I expect?

  • thread-safety

  • (im)mutability

  • good names, small methods, SOLID, …​ don’t help here

  • observed behavior != contract

  • how many interface implementations am I supposed to check?

  • what if I have to implement an interface?

  • You’re code is not a special snowflake - it’s the all singing all dancing crap of the world.

  • I am in a hurry and have to get shit done.

Tests

I care even less about your tests!

How do you test this?

  • "for all" propositions

  • thread-safety

  • (im)mutability

  • do you have tests for interfaces?

  • test coverage better be > 90%.

Tests

Ever heard RTFT? (Read The &*☠# Tests)

No?

What was I thinking about?

Comments Age

That’s like saying "Car’s crash".

So? Do we get rid of them?

  • crashes are caused by negligence

  • are often punishable by law

  • do not harm the overall benefit

Comments Age

What about names?

  • do they age?

  • do you update them?

Yes?!

Then update the comments, too!

The Costs Of Comments

or

Why Everybody Hates Comments

Initial Composition

Writing a comment is harder…​

  • …​ the later it is done

  • …​ the more complex the code is

  • …​ the more precise the comment is

Usually affordable compared to writing code and tests.

  • cost is capped when abstraction works well

Maintenance

What do to with comments when code changes?

  • updating ⇝ takes time

  • leaving unchanged ⇝ causes confusion

  • deletion ⇝ wastes past efforts

Whatever schema you decide onmaintenance is critical!

Maintenance

  • changing comments takes little time

  • but finding them can be hard

⇝ Comments and code must be close!

  • pesky, time-consuming, error-prone

Confusion

Comments that are

  • outdated

  • ambiguous

  • lacking detail

cause confusion!

Confusion

Costs are unpredictable but potentially enormous!

Deteriorates trust in comments.

  • good coding techniques reduce risk

Obstruction

Takes up screen space.

(Fold that shit!)

Why Everybody Really Hates Comments

  • they may be hard to write

  • they turn nothing green

  • nobody gets a pat on the back for a clever comment

Get over it!

The Benefits Of Comments

Small note: Benefits suffer from diminishing returns.

Explain What Happens

Duh!

  • intrinsically redundant

  • can cause confusion

Might be necessary for arcane language features.

Keep Abstractions Intact

Every unit of code provides an abstraction.

  • do one thing and to it well

  • hide how it does it

  • should not require us to look past the abstraction

The core to modularizing any non-trivial problem!

Keep Abstractions Intact

Abstractions provide two benefits:

  • reuse code

  • reuse understanding

Comments can help with both!

  • abstractions lose value if I have to step into them

  • tests, clean code, …​ only shines then

  • you have to build a new context

Top Down vs Bottom Up

  • most people learn better top down

  • clean code, tests, …​ are a bottom up approach

Comments can be signposts, helping to stay on the right level of abstraction.

  • similar to keeping abstractions intact

Document Intent

Context is invaluable when revisiting code!

  • why?

  • no seriously, WHY?

  • why the &*☠#?!

Document Intent

  • other tools contain this info

  • working through them takes time

  • and is transient!

Comments can be 2nd line of defense.

Spur Redesign

It’s funny how writing documentation can spur redesign: it’s easier to simplify a complex API than try to document it completely.

(Mike Bostok on Twitter.)

Looking Closer…​

  • actuality

  • locality

  • alternatives

Actuality

  • some comments need to be very up-to-date

  • others can be slightly or even totally outdated

This influences costs:

  • maintenance

  • confusion

Locality

How far can a comment be away from what it describes?

  • some must basically be on the same line to make any sense at all

  • others might span several concepts so they can be some classes away

It is hard to update far-away comments!

Alternatives

There are plenty of alternatives to comments.

But not all work for everything.

  • clean code

  • tests, demos

  • version control

  • issue tracker

  • wiki

What does it do?

public int activeUserCountSince(Date date) {
    int activeUserCount = 0;
    // loop through the users
    for (User user : users)
        // check whether user logged in
        if (user.loggedInSince(date))
            // increase activeUserCount
            activeUserCount++;
    return activeUserCount;
}

Narrations

Usually inline comments.

  • explain what the code does

  • speak on a very technical level

Analysis

Actuality
  • very high

  • need to be absolutely up to date!

Location
  • right on the narrated line(s)

Alternatives
  • good names

  • transparent design

  • well-known patterns

Costs

  • composition: medium

  • maintenance: high

  • confusion: high risk

  • obstruction: yes, can’t be hidden

Benefits

  • explain what happens: yes

  • keep abstractions intact: no

  • top down over bottom up: no

  • documenting intent: a little

Verdict

Narrations suck!

 

With one exception:

  • arcane language features are used

  • there is no alternative

  • there is no way to improve readability

What Does It Promise?

public interface Map<K, V> {
    /**
     * ...............................
     * ................................
     * ....................................
     * ....................................
     *
     * @return .......................
     *         ....................
     */
    int size();
}
public interface Map<K, V> {
    /**
     * Returns the number of key-value
     * mappings in this map. ..........
     * ....................................
     * ....................................
     *
     * @return the number of key-value
     *         mappings in this map
     */
    int size();
}
public interface Map<K, V> {
    /**
     * Returns the number of key-value
     * mappings in this map. If the map
     * contains more than Integer.MAX_VALUE
     * elements, returns Integer.MAX_VALUE.
     *
     * @return the number of key-value
     *         mappings in this map
     */
    int size();
}

Contract Comments

(or just Contracts)

Usually JavaDoc on classes and methods.

They define

  • the code’s central abstraction

  • pre- and postconditions

  • quirks

  • highlight "define" (not "describe")

  • they make a promise

Analysis

Actuality
  • high

Location
  • right on the class or method

Alternatives
  • good names (limited)

  • tests (limited)

Costs

  • composition: high

  • maintenance: considerable

  • confusion: high risk

  • obstruction:

    • can be hidden

    • and viewed on demand

Benefits

  • explain what happens: yes

  • keep abstractions intact: yes

  • top down over bottom up: to a degree

  • documenting intent: no

Verdict

It’s complicated.

 

  • costs are high if code changes often

  • benefits are high if code is read often

⇝ The more stable & reused the code, the better the outcome!

  • "resused" often implies "stable" by necessity

  • good documentation improves discoverability and adoption

How does it work?

/**
 * When keys are Comparable, this class may
 * use comparison order among keys to help
 * break ties.
 */
public class HashMap<K, V> { }
/**
 * When keys are Comparable, this class may
 * use comparison order among keys to help
 * break ties.
 */
public class HashMap<K, V> {
    /* This map usually acts as a binned
     * (bucketed) hash table, but when bins
     * get too large, they are transformed
     * into bins of TreeNodes, each
     * structured similarly to those in
     * java.util.TreeMap. */
}
  • another example: a class explaining that a factory is required

Technical Context

Often non-Javadoc blocks at the beginning of a class/method.

  • clarify what code is for

  • when to use it and when not

  • explain implementation details

(This is not a contract!)

  • can even give examples

  • contracts make a promise, context comments explain why it was made

Analysis

Actuality
  • not that important

Location
  • not that important

Alternatives
  • demos

  • existing code (limited)

Costs

  • composition: moderate

  • maintenance: not so much

  • confusion: possible

  • obstruction:

    • can be hidden

    • and viewed on demand

Benefits

  • explain what happens: somewhat

  • keep abstractions intact: a little

  • top down over bottom up: to a degree

  • documenting intent: yes

Verdict

A clear winner!

 

  • costs are moderate

  • benefits are considerable

  • avoid confusion with contracts

OMG, why?!

public Color randomFavoriteColor() {
    while (true)
        Color favorite = randomColor();
        if (isNotWhiteish(favorite))
            return favorite;
}
public Color randomFavoriteColor() {
    while (true)
        Color favorite = randomColor();
        // In China white is often seen
        // as a color of mourning and
        // some Chinese users did not
        // like it. We hence disallow
        // whitish colors as favorites.
        // For details see issue #1534.
        if (isNotWhitish(favorite))
            return favorite;
}

Historical Context

  • clarifies why (oh why?) code looks the way it does

  • can document paths not taken

Analysis

Actuality
  • negligible

Location
  • not that important

Alternatives
  • commit messages

  • issues, wikis

Costs

  • composition: moderate

  • maintenance: negligible

  • confusion: low

  • obstruction:

    • can be hidden

    • and viewed on demand

Benefits

  • explain what happens: somewhat

  • keep abstractions intact: no

  • top down over bottom up: no

  • documenting intent: yes

Verdict

Even better!

 

  • costs are negligible

  • benefits are considerable

These are great breadcrumbs when tracking down bugs!

Where Does This Leave Us?

Let’s move away from

All comments are failures.

Instead

Comments are a tool to facilitate understanding. We should use it wisely!

Clean Comments

For individual comments:

  • make obvious which kind they are

  • put yourself in your reader’s mind

  • strive for high locality

  • get them reviewed

  • use phrases like "at the time of writing"

  • use @apiNote, @implNote

  • use different styles: /* vs / vs //

Clean Comments

This is my proposal:

  • avoid narrations whenever possible

  • always have a paragraph that explains a class’s central abstraction

  • add contracts to reused APIs

  • provide as much context as possible

Clean Comments

But the details depend on many factors:

  • team:

    • size

    • technical backgrounds

  • code base:

    • size

    • heterogeneity

    • ownership

Clean Comments

So:

  • get the team together and speak freely about comments

  • go through the code base anddiscuss concrete examples

  • settle on a shared approach and include it in your style guide

  • use pair programming or code reviews to adapt and enforce

Questions?

Find Me

Me

you can hire me

since 2016: Java channel editor at SitePoint

2014-2016: Java developer at Disy

2011-2014: Java developer at Fraunhofer ISI

until 2010: CS and Math at TU Dortmund

Image Credits

Comment Your &*☠# Code Nicolai Parlog codefx.org / @nipafx Devoxx PL @devoxxpl hljs.initHighlightingOnLoad(); hljs.configure({tabReplace: ' '}) Nicolai Parlog / codefx.org / @nipafx Devoxx PL / @devoxxpl document.addEventListener('DOMContentLoaded', function () { document.body.appendChild(document.querySelector('footer')); })