Every once in a while, there are always some annoying posts popping up on the web with the idea that you shouldn’t write comments for the code, the only reason it exists is because the code itself isn’t good enough. I cannot agree with these arguments at all.

Nor are their views entirely wrong. No one can say their code is good enough. The code itself can slowly get worse. Do you know when code rots the most? When you haven’t touched these codes in six months! When you look back and read it again, you’ll be curious: “What did this author really think?” (So, using Git blame to look at the history, I didn’t expect the code to be written by myself, because it’s your code.) )

The argument against commenters is that the only reason you need comments is that your code isn’t “clear” enough. If the code is refactored, named, and organized better, these comments are not needed.

Today, when the entire project and problem space is in your head, you naturally feel that the code is clean, clear, and elegant. But when six months later, or when the CTO suddenly finds a very serious bug on the production system, and some poor guy has to debug your code with the supervisor on the watch, the code may have been a little blurry to you.

You’re so familiar with a piece of code that tries to understand situations other people can’t understand, which is a very difficult skill to master. However, it is invaluable and almost as important as the ability to write code right the first time. In industry, basically no one is a loner. Even if you’re actually writing code on your own, you’ll forget why the code was written this way or the exact purpose of the core part of the “engineering code” late last night. In the future, once you leave your job, the person who will replace you will have to understand every small preference and habit that is only hidden in your head.

So, writing a comment that seems too superficial even now is not a bad thing. Sometimes, it can even be of great help.

Some people claim that removing comments will make the code better because it forces you to write cleaner code. I don’t think so, either, because I don’t think anyone would actually write some subprime code and write some comments to explain this behavior (except for // TODO: This is a temporary workaround, I’ll fix it later). We all write code that we think is best under various external conditions (usually time).

The problem with refactoring code to remove comments is that this effort often backfires and produces worse code. A typical example is to reconstruct a complex line of code, extract it into a separate function, and take a literal name. This behavior looks great, but now you bring a context switch point for people reading the code. Instead of the real code, it was a function call, so they had to scroll to where the function was defined, remember and compare the parameters of the function declaration and call, and substitute the function return value to the place where the call was made.

In addition, clear function names can only provide very short comments. Any comment that requires an extra short phrase cannot (or shouldn’t) be summarized in a function name. So, you end up with a function that has comments on it.

It is true that a very short function can lead to confusing and more complex code. If I see a function like this, I search for where it is called. If there was only one place, I wondered if it was a generic block of code that really encapsulated global logic (such as NameToUserID), or whether the function relied heavily on specific states and implementations on the caller and didn’t work correctly elsewhere. As you extract this code into a function, you essentially expose the implementation details in the rest of the codebase, and it is inappropriate to make such hasty decisions. Even if you know that this function should not be called by others, others will call it in some places, even if it is not appropriate to do so.

Issues related to small functions are explained in more detail in Cindy Sridharan’s post on the medium website[1].

We can even delve into the comparisons and trade-offs of long and short variable names, but stop there, it’s generally not possible to accept longer variable names. Unless your variable name is the full comment you want to write, you’ll still lose information and have to add it to the comment. I think we can agree: usernameStrippedOfSpacesWithDotCSVExtension is a terrible variable name.

I’m not saying we shouldn’t refine the code to make it clearer and more elegant. Absolutely! This is a characteristic of a great developer. However, code clarity and annotations are orthogologous, and well-written comments are also traits of great developers.

The examples of bad comments given in these discussions are minor errors that are rarely encountered in practical work except for those enlightenment programming courses.

Yes, this note is clear, but not very useful. But at the same time, it doesn’t actually hurt either. When browsing through code, while a bit undesirable, it can easily be overlooked. If a developer could include a useful comment in it that would save me hours of keyboard time, I’d rather look at hundreds of simple comments than no comments.

I’m pretty sure that no code will say “Dude, this code is very easy to understand, so no comment needs to be provided.” The reality is the exact opposite.

Actually, I found some code that is severely missing comments – the Go Standard Library. Its code is very sophisticated, but in many cases, if the code is not deeply understood before it is read, then understanding why they are designed the way it is will be challenging. The addition of comments to explain the logic and design intent of the code will make the Go Standard Library easier to read. In this article, I’m mostly talking about comments in implementation code, rather than the usual documentation comments for public functions (in general, they’re pretty good).

Another example that the decommenters like to come up with can be shown (to prove the argument) with the following concise and powerful picture:

Ha, very funny, someone changed the inside of the bottle but didn’t update the label on the outside.

However, this was a problem 20 years ago, when code reviews were not usually conducted. However, code reviews are now very common. If checking that comments and implementations match is not part of your code review process, it’s a good idea to check your code review process.

This is not to say that mistakes cannot be made, in fact I just filed a bug yesterday with “inconsistencies in comments and implementations”. Statements like “no comments are better than bad comments” sound right at first, but when you realize that without comments, developers can guess the code much more likely than if they were wrong.

Even if this does happen and the code is modified, you can still get valuable information: what the code used to do before. The modification is only slightly different from the original, but it still does basically the same function. For versioning and backward compatibility, how often does the same function change dramatically in functionality without changing its name and signature? Basically very little.

For example, the bug I found yesterday, we call client. SetKeepAlive(60)。 A note for the SetKeepAlive function is “The client needs to wait a specified number of hours, in seconds, before SetKeepAlive sends a PING request.” Looks great, doesn’t it? Know that I noticed that the parameter to SetKeepAlive is time. Duration。 If no other unit is specified, the integer 60 uses the default unit nanoseconds of Go’s duration. Hey, someone updated the function to replace the Int with the Duration type. Interestingly, it’s still rounded down to the nearest number of seconds, so the comment isn’t incorrect, it’s just misleading.

The most important comment is why it should be commented out. Why is the code executed by design? Why does this ID need to be less than 24 characters? Why hide this option under Linux? Etcetera. The reason why these problems are important is that you can’t extract them from the code. These comments summarize the lessons learned by developers, business or system-level constraints, etc., which are of immeasurable value and are almost impossible to obtain from other sources (e.g., function names should reflect what the function does rather than why).

Those comments that illustrate the functionality of the code are often not particularly useful, because with enough time and effort, you will always be able to understand the function of the code. Essentially, through a function definition, the code will tend to tell you what it does, but that doesn’t mean you shouldn’t write any comments. It is true that you should strive to write the clearest and most concise code, but comments do not require any additional runtime overhead, and if you feel that someone will misunderstand some code or have difficulty understanding, you should write some comments. At the very least, this will save them half an hour to understand your code, and these comments will also go a long way toward helping them avoid modifying or using your code incorrectly that can lead to bugs.

Some people think that a functional test case for a function is equivalent to a document. In a way, it is. However, in my efficiency document table, it has a very low priority. Why? Because they are extremely precise and trivial, they cover only a small part of the function. Each test tests only one specific input and the output that matches it. In any case of more than one simple function, you will most likely need a large string of code to build the inputs and outputs.

For most coders, describing the main function of a function is much easier than writing code to test it completely. Many times my test code is multiplied by the number of lines of test code as the function implementation itself, but documentation comments are only a few lines.

In addition, the test only explains the function of the function. What are the design features of the function? They can’t explain why, but as mentioned earlier, design purpose and intent are always more important.

You really should test your code, and with some boundary test cases, testing is useful for determining whether your code will work properly under boundary conditions. But in general, if we get to the point where we have to read test cases to understand the code, it’s already a red flag that we need to write more and better comments.

Aside from some very simple examples, the boundary between useful and unused comments is very difficult to find. So, I’d rather people be on the side of writing more notes. You can’t know who the next person who might read your code will be, so what can help them is write as many comments as you can. Try to write until you think there is too much, and then write more, and the number is estimated to be just right.

via: https://npf.io/2017/11/comments/

Author: Nate Finch[2] Translator: arthurlee[3] Proofreader: rxcai[4]

This article was compiled by GCTT[5] originally, and is honored by Go Chinese.com[6].

Posts on the medium website: https://medium.com/@copyconstruct/small-functions-considered-harmful-91035d316c29

Nate Finch: https://npf.io/about/

arthurlee: https://github.com/arthurlee

rxcai: https://github.com/rxcai

GCTT: https://github.com/studygolang/GCTT

Go Chinese: https://studygolang.com/

Recommended reading

Use viper to implement the merging of yaml configuration files