Getty Images/iStockphoto

Tip

Best practices for writing clean code comments

Well-written code comments are a great tool to explain code intent. Use these tips to ensure your comments are adding value to source code, not cluttering it up.

Code comments are a commonly misunderstood feature of programming languages. Getting them right can be the difference between enhancing source code and adding confusion.

Helpful comments in your code enable other developers to more quickly understand the design of your codebase. When that happens, they can contribute code that reinforces the same ideas and design. However, it can be tricky to strike the right balance between comment quality and quantity -- especially for beginners.

Use the following tips to write code comments that create more readable and maintainable code.

What are code comments?

Code comments are text in the source code that the compiler or interpreter ignores when running a program. They are annotations that provide context for others looking at the code. Different programming languages have different syntaxes to denote comments in source code. For example, Java comments use a combination of slashes and asterisks, Python uses a hashtag and HTML uses a combination of exclamation points and angle brackets.

Code is written by people for computers to read and execute. In this way, code serves two purposes:

  • To allow developers to write and understand code.
  • To execute desired operations on a computer.

Because computers simply read and execute code, comments are best reserved to explain the intent of the code rather than what it does. If one wants to understand what the code does, the code should already be written to a standard where one can read the lines directly and generally understand what will happen in execution. There are some exceptions to this, but it's best summed up with the following statement: Code does what it's written for, but the intent is unexplained.

How are code comments used?

Developers can use code comments to explain high-level code intent, provide documentation or describe a bug fix.

Beyond just explanation, comments serve a greater purpose in software maintenance. They can highlight potential edge cases, mark areas intended for future improvement and provide historical context for specific coding approaches. Comments become particularly valuable when describing workarounds, performance considerations or system limitations that are not apparent from the code's surface-level behavior.

When working with others, well-crafted comments lead to smoother team interactions by reducing learning curves and providing insights into code structure and intent. They add the human element to source code, turning it from an executable set of instructions into a communicative resource that supports ongoing development, debugging, collaboration and optimization.

Consider the following best practices and examples of what useful comments might look like.

5 best practices for clean code comments

Overall, there are five guiding principles for cleaner code comments:

  1. Comments should explain why code is written the way it is, rather than explaining what the code does. Comments should provide context about the reasoning behind a specific implementation, such as explaining a complex algorithm's rationale or why a particular approach was chosen, rather than merely restating the code's basic functionality.
  2. Comments should be nonduplicative of code. Comments should add value beyond what the code itself already clearly communicates, avoiding redundant descriptions that simply restate the code's obvious actions and instead offering insights not immediately apparent from reading the code.
  3. Comments should clarify, not confuse. Good comments should illuminate code's purpose and behavior, using clear and precise language that helps developers understand the code's intent, avoiding technical jargon or overly complex explanations that might further obscure the code's meaning.
  4. Comments should be brief. If your comments are extensive, you likely have problematic code. Extended comments often indicate that code is too complex or unclear, suggesting that the code itself should be refactored to be more self-explanatory, with comments serving as succinct, targeted explanations of nuanced or intricate logic. Overly complicated code is difficult to read, and this, in turn, makes commenting a challenge. Refactoring to where the code is easily explainable saves time for others in understanding the code, as well as any future code maintenance.
  5. Comments should provide explanations for nonobvious code. Comments are most valuable when they explain non-intuitive aspects of code, such as workarounds for specific edge cases, performance considerations, historical context or complex business logic that isn't immediately clear from the code's structure. For example, comments on REST endpoints and API methods might be useful because they are likely used by another team that could benefit from the context. Comments that summarize complex, idiosyncratic code help save time in code review and future maintenance.

Common code comment mistakes

To highlight how code comments should describe high-level intent instead of what the code does, consider this login function in Python:

@app.route('/login', methods=['POST'])
def login():
   info = json.loads(request.data)
   username = info.get('username')
   password = info.get('password')
   user = User.objects(name=username, password=password).first()
   
   if user:
       login_user(user)
       return jsonify(user.to_json())
   else:
       return jsonify({"status": 401,
                       "reason": "Username or Password Error"})

On the first line of the function, the data included with the request is parsed into a JSON object and set to the variable info. On the next two lines, the username and password are read from the info JSON object. Then, a variable user is set to the result of checking the user model for entries with that username and password. Next, the code goes through an if statement that checks the user variable. If the user variable is not null, the login_user function is called, and the user info is returned as a JSON object. However, else -- when the user variable is empty or null -- results in a 401 error to indicate that the user does not exist with that username and password.

In this scenario, developers should avoid adding code comments that duplicate the lines of code themselves. Once you know that the json.loads function takes a string and returns a JSON object, you won't benefit from a comment that relays the same information. If you forget what the function does, it's best to look up the documentation for the function.

If there was a comment explaining the code at this granular level, it could be incorrect or outdated based on differences between you and the original developer, such as language version, OS or external library versions. Duplicative code comments clutter the code and make it harder to read, which introduces confusion and possible discrepancies. See the same Python example with duplicative, overly descriptive comments applied:

@app.route('/login', methods=['POST'])
def login(): 
   info = json.loads(request.data)
   # Access the 'username' key from the 
   # 'info' dictionary using the get method
   # The get method returns None if the key 
   # doesn't exist, avoiding KeyError
   # Store the result in the 'username' variable
   username = info.get('username')
   password = info.get('password')

   # Query the User collection in the database 
   # using MongoEngine's objects attribute
   # The query filters for documents where
   # 'name' equals 'username' and 'password' equals 'password'
   # The 'first()' method is called to 
   # retrieve only the first matching document
   # If no matching document is found, 'user' will be None
   user = User.objects(name=username, password=password).first()
   
   if user:
       login_user(user)
       return jsonify(user.to_json())
   else:
       return jsonify({"status": 401,
                       "reason": "Username or Password Error"})

Examples of good code comments

Useful comments should add value to and improve the code by clarifying the code's intent and providing a brief, high-level summary. For example, the following comments add value to the same Python login function:

# Log in existing users or return 401
@app.route('/login', methods=['POST'])
def login():
   info = json.loads(request.data)
   username = info.get('username')
   password = info.get('password')
   # get a matching user from the database
   user = User.objects(name=username, password=password).first()
   
   if user:
       login_user(user)
       return jsonify(user.to_json())
   else:
       return jsonify({"status": 401,
                       "reason": "Username or Password Error"})

These comments provide a high-level understanding and overall flow of the function. Any other coders working on this function should be able to understand the comments and code because of their familiarity with the codebase and frameworks in use.

Another code comment best practice that this example highlights is to keep comments brief. The comments on this block of code don't add extraneous information and just focus on high-level explanation.

Consider this second example of a well-commented code snippet from a GitHub course on Python, with more of the guiding principles in action:

# get local date - does not account for time zone
# note: date was imported at top of script
def stringdate():
   today = date.today()
   date_list = str(today).split('-')
   # build string in format 01-01-2000
   date_string = date_list[1] + "-" + date_list[2] + "-" + date_list[0]
   return date_string

The first comment describes the function at a high level and shares a condition that is important for any developer using the function to know. The second comment focuses on how the date is imported at the top of the script. This comment helps developers learning the process to better understand the function. The third comment -- the inline comment -- helps programmers quickly understand what the line does to set the date_string variable. All three comments are non-duplicative, not overly complex and add valuable context where needed.

Matt Grasberger is a DevOps engineer with experience in test automation, software development, and designing automated processes to reduce work.

Dig Deeper on Software design and development