Writing system software: code comments

Table of Contents

Writing system software: code comments. - <antirez>

作者按照功能对注释进行了分类,以及解释每种分类在什么情况应该使用,什么情况下面不应该使用。

1. Is comment needed

首先作者对是否要写注释表达了明确的意见:就是注释一定要写,而且不能被代码取代。

  1. 大部分注释不是解释代码做了什么,而是解释为什么要这么做,这点在代码上是没有办法体现的。
  2. 即便是解释代码做了什么,注释也可以帮助读者减轻认知负担,直接从注释中明白作者的代码意图。

Not everybody thinks likewise. Many believe that comments are useless if the code is solid enough. The idea is that when everything is well designed, the code itself documents what the code is doing, hence code comments are superfluous. I disagree with that vision for two main reasons:

  1. Many comments don't explain what the code is doing. They explain what you can't understand just from what the code does. Often this missing information is why the code is doing a certain action, or why it’s doing something that is clear instead of something else that would feel more natural.
  2. While it is not generally useful to document, line by line, what the code is doing, because it is understandable just by reading it, a key goal in writing readable code is to lower the amount of effort and the number of details the reader should take into her or his head while reading some code. So comments can be, for me, a tool for lowering the cognitive load of the reader.

2. Classification

按照功能作用,注释可以分为下面这么几类:

  • Function comments
  • Design comments
  • Why comments.
  • Teacher comments
  • Checklist comments
  • Guide comments
  • Trivial comments
  • Debt comments
  • Backup comments

3. Function Comments

函数注释可以帮助读者快速了解这个函数的功能,input和output是什么,有什么side-effect, 而且这个注释最好和代码放在一起。

The goal of a function comment is to prevent the reader from reading code in the first place. Instead, after reading the comment, it should be possible to consider some code as a black box that should obey certain rules. Normally function comments are at the top of functions definitions, but they may be at other places, documenting classes, macros, or other functionally isolated blocks of code that define some interface.

Function comments are actually a form of in-line API documentation. If the function comment is written well enough, the user should be able most of the times to jump back to what she was reading (reading the code calling such API) without having to read the implementation of a function, a class, a macro, or whatever.

Among all the kinds of comments, these are the ones most widely accepted by the programming community at large as needed. The only point to analyze is if it is a good idea to place comments that are largely API reference documentation inside the code itself. For me the answer is simple: I want the API documentation to exactly match the code. As the code is changed, the documentation should be changed. For this reason, by using function comments as a prologue of functions or other elements, we make the API documentation close to the code, accomplishing three results:

  • As the code is changed, the documentation can be easily changed at the same time, without the risk of making the API reference stale.
  • This approach maximizes the probability that the author of the change, that should be the one better understanding the change, will also be the author of the API documentation change.
  • Reading the code is handy to find the documentation of functions or methods directly where they are defined, so that the reader of the code can focus solely on the code, instead of context switching between code and documentation.

4. Design Comments

设计注释解释这个模块的行为,之外还应该包括使用具体实现细节,各种trade-off, 以及其他可选方案等等。

While a "function comment" is usually located at the start of a function, a design comment is more often located at the start of a file. The design comment basically states how and why a given piece of code uses certain algorithms, techniques, tricks, and implementation. It is an higher level overview of what you'll see implemented in the code. With such background, reading the code will be simpler. Moreover I tend to trust more code where I can find design notes. At least I know that some kind of explicit design phase happened, at some point, during the development process.

In my experience design comments are also very useful in order to state, in case the solution proposed by the implementation looks a bit too trivial, what were the competing solutions and why a very simple solution was considered to be enough for the case at hand. If the design is correct, the reader will convince herself that the solution is appropriate and that such simplicity comes from a process, not from being lazy or only knowing how to code basic things.

5. Why Comments

Why comments explain the reason why the code is doing something, even if what the code is doing is crystal clear.

6. Teacher Comments

教学注释可以帮助读者快速了解某些重要的领域知识,可以帮助更多的领域外的开发者参与进来。

Teacher comments don't try to explain the code itself or certain side effects we should be aware of. They teach instead the domain (for example math, computer graphics, networking, statistics, complex data structures) in which the code is operating, that may be one outside of the reader skills set, or is simply too full of details to recall all them from memory.

I think teacher comments are of huge value. They teach something in case the reader is not aware of such concepts, or at least provide a starting point for further investigation. But this in turn means that a teacher comment increases the amount of programmers that can read some code path: writing code that can be read by many programmers is a major goal of mine. There are developers that may not have math skills but are very solid programmers that can contribute some wonderful fix or optimization. And in general code should be read other than being executed, since is written by humans for other humans.

7. Checklist Comments

清单注释是提醒开发者那些地方需要注意:比如几个函数需要一起使用,之间顺序如何,如果A位置修改那么B位置也需要修改等等。 清单注释和Why注释出现的context有很相似的地方,我认为通常是算法和逻辑上有比较tricky的地方,需要精巧的配合。 而Why注释比较强调为什么需要这么做,清单注释则强调应该怎么做。

This is a very common and odd one: sometimes because of language limitations, design issues, or simply because of the natural complexity arising in systems, it is not possible to centralize a given concept or interface in one piece, so there are places in the code that tells you to remember to do things in some other place of the code.

Specifically a checklist comment does one or both of the following things:

  • It tells you a set of actions to do when something is modified.
  • It warns you about the way certain changes should be operated.

The checklist comment is also useful in a context similar to when certain "why comments" are used: when it is not obvious why some code must be executed at a given place, after or before something. But while the why comment may tell you why a statement is there, the checklist comment used in the same case is more biased towards telling you what rules to follow if you want to modify it (in this case the rule is, follow a given ordering), without breaking the code behavior.

8. Guide Comment

指导注释存在的唯一理由就是降低读者的认知负担:不要重复code, 不要在里面涉及设计内容。我理解指导注释可以帮助读者在阅读代码时 有种行云流水的感觉,不用在某段代码的时候突然卡壳。

I abuse guide comments at such a level that probably, the majority of comments in Redis are guide comments. Moreover guide comments are exactly what most people believe to be completely useless comments.

  • They don't state what is not clear from the code.
  • There are no design hints in guide comments.

Guide comments do a single thing: they babysit the reader, assist her while processing what is written in the source code by providing clear division, rhythm, and introducing what you are going to read.

Guide comments’ sole reason to exist is to lower the cognitive load of the programmer reading some code.

Redis is literally ridden of guide comments, so basically every file you open will contain plenty of them. Why bother? Of all the comment types I analyzed so far in this blog post, I'll admit that this is absolutely the most subjective one. I don't value code without such comments as less good, yet I firmly believe that if people regard the Redis code as readable, some part of the reason is because of all the guide comments.

Guide comments have some usefulness other than the stated ones. Since they clearly divide the code in isolated sections, an addition to the code is very likely to be inserted in the appropriate section, instead of ending in some random part. To have related statements nearby is a big readability win.

9. Trivial Comments

这种注释没有任何价值

10. Debt Comments

Debt comments are technical debts statements hard coded inside the source code itself.

11. Backup Comments

通过注释将部分遗留代码保存下来。如果某些遗留代码希望保留下来的,通常说明工作并没有完成, 而历史记录可以通过Git来保存,所以这类注释通常没有什么存在的必要。

Finally backup comments are the ones where the developer comments older versions of some code block or even a whole function, because she or he is insecure about the change that was operated in the new one. What is puzzling is that this still happens now that we have Git. I guess people have an uneasy feeling about losing that code fragment, considered more sane or stable, in some years old commit.

But source code is not for making backups. If you want to save an older version of a function or code part, your work is not finished and cannot be committed. Either make sure the new function is better than the past one, or take it just in your development tree until you are sure.

12. Comments as an analysis tool

写注释和文档都有助于帮你理清思路和定位问题

Comments are rubber duck debugging on steroids, except you are not talking with a rubber duck, but with the future reader of the code, which is more intimidating than a rubber duck, and can use Twitter. So in the process you really try to understand if what you are stating is acceptable, honorable, good enough. And if it is not, you make your homework, and come up with something more decent.

It is the same process that happens while writing documentation: the writer attempts to provide the gist of what a given piece of code does, what are the guarantees, the side effects. This is often a bug hunting opportunity. It is very easy while describing something to find that it has holes… You can't really describe it all because you are not sure about a given behavior: such behavior is just emerging from complexity, at random. You really don't want that, so you go back and fix it all. I find this a splendid reason to write comments.

13. Writing good comments is harder than writing good code

编写注释和文档除了有助于更好地理解问题域和编码之外,还能锻炼写作能力。而这种写作能力,在更多的方面会帮助到你。

You may think that writing comments is a lesser noble form of work. After all you can code! However consider this: code is a set of statement and function calls, or whatever your programming paradigm is. Sometimes such statements do not make much sense, honestly, if the code is not good. Comments require always to have some design process ongoing, and to understand the code you are writing in a deeper sense. On top of that, in order to write good comments, you have to develop your writing skills. The same writing skills will assist you writing emails, documentation, design documents, blog posts, and commit messages.

I write code because I have an urgent sense to share and communicate more than anything else. Comments coadiuvate the code, assist it, describe our efforts, and after all I love writing them as much as I love writing code itself.