What is your personal approach/take on commenting?

2019-03-25 04:28发布

Duplicate

What are your hard rules about commenting?

A Developer I work with had some things to say about commenting that were interesting to me (see below). What is your personal approach/take on commenting?

"I don't add comments to code unless its a simple heading or there's a
platform-bug or a necessary work-around that isn't obvious. Code can change and comments may become misleading. Code should be
self-documenting in its use of descriptive names and its logical
organization - and its solutions should be the cleanest/simplest way
to perform a given task. If a programmer can't tell what a program
does by only reading the code, then he's not ready to alter it.
Commenting tends to be a crutch for writing something complex or
non-obvious - my goal is to always write clean and simple code."

"I think there a few camps when it comes to commenting, the enterprisey-type who think they're writing an API and some grand code-library that will be used for generations to come, the craftsman-like programmer that thinks code says what it does clearer than a comment could, and novices that write verbose/unclear code so as to need to leave notes to themselves as to why they did something."

26条回答
戒情不戒烟
2楼-- · 2019-03-25 05:00

You need documentation (in some form; not always comments) for a local understanding of the code. Code by itself tells you what it does, if you read all of it and can keep it all in mind. (More on this below.) Comments are best for informal or semiformal documentation.

Many people say comments are a code smell, replaceable by refactoring, better naming, and tests. While this is true of bad comments (which are legion), it's easy to jump to concluding it's always so, and hallelujah, no more comments. This puts all the burden of local documentation -- too much of it, I think -- on naming and tests.

Document the contract of each function and, for each type of object, what it represents and any constraints on a valid representation (technically, the abstraction function and representation invariant). Use executable, testable documentation where practical (doctests, unit tests, assertions), but also write short comments giving the gist where helpful. (Where tests take the form of examples, they're incomplete; where they're complete, precise contracts, they can be as much work to grok as the code itself.) Write top-level comments for each module and each project; these can explain conventions that keep all your other comments (and code) short. (This supports naming-as-documentation: with conventions established, and a place we can expect to find subtleties noted, we can be confident more often that the names tell all we need to know.) Longer, stylized, irritatingly redundant Javadocs have their uses, but helped generate the backlash.

(For instance, this:

Perform an n-fold frobulation.
@param n the number of times to frobulate
@param x the x-coordinate of the center of frobulation
@param y the y-coordinate of the center of frobulation
@param z the z-coordinate of the center of frobulation

could be like "Frobulate n times around the center (x,y,z)." Comments don't have to be a chore to read and write.)

I don't always do as I say here; it depends on how much I value the code and who I expect to read it. But learning how to write this way made me a better programmer even when cutting corners.

Back on the claim that we document for the sake of local understanding: what does this function do?

def is_even(n): return is_odd(n-1)

Tests if an integer is even? If is_odd() tests if an integer is odd, then yes, that works. Suppose we had this:

def is_odd(n): return is_even(n-1)

The same reasoning says this is_odd() tests if an integer is odd. Put them together, of course, and neither works, even though each works if the other does. Change it a bit and we'd have code that does work, but only for natural numbers, while still locally looking like it works for integers. In microcosm that's what understanding a codebase is like: tracing dependencies around in circles to try to reverse-engineer assumptions the author could have explained in a line or two if they'd bothered. I hate the expense of spirit thoughtless coders have put me to this way over the past couple of decades: oh, this method looks like it has the side effect of farbuttling the warpcore... always? Well, if odd crobuncles desaturate, at least; do they? Better check all the crobuncle-handling code... which will pose its own challenges to understanding. Good documentation cuts this O(n) pointer-chasing down to O(1): e.g. knowing a function's contract and the contracts of the things it explicitly uses, the function's code should make sense with no further knowledge of the system. (Here, contracts saying is_even() and is_odd() work on natural numbers would tell us that both functions need to test for n==0.)

查看更多
何必那么认真
3楼-- · 2019-03-25 05:01

I also generally subscribe to the self-documenting code idea, so I think your developer friend gives good advice, and I won't repeat that, but there are definitely many situations where comments are necessary.

A lot of times I think it boils down to how close the implementation is to the types of ordinary or easy abstractions that code-readers in the future are going to be comfortable with or more generally to what degree the code tells the entire story. This will result in more or fewer comments depending on the type of programming language and project.

So, for example if you were using some kind of C-style pointer arithmetic in an unsafe C# code block, you shouldn't expect C# programmers to easily switch from C# code reading (which is probably typically more declarative or at least less about lower-level pointer manipulation) to be able to understand what your unsafe code is doing.

Another example is when you need to do some work deriving or researching an algorithm or equation or something that is not going to end up in your code but will be necessary to understand if anyone needs to modify your code significantly. You should document this somewhere and having at least a reference directly in the relevant code section will help a lot.

查看更多
劳资没心,怎么记你
4楼-- · 2019-03-25 05:01

I don't think it matters how many or how few comments your code contains. If your code contains comments, they have to maintained, just like the rest of your code.

EDIT: That sounded a bit pompous, but I think that too many people forget that even the names of the variables, or the structures we use in the code, are all simply "tags" - they only have meaning to us, because our brains see a string of characters such as customerNumber and understand that it is a customer number. And while it's true that comments lack any "enforcement" by the compiler, they aren't so far removed. They are meant to convey meaning to another person, a human programmer that is reading the text of the program.

查看更多
倾城 Initia
5楼-- · 2019-03-25 05:02

There's a tragic flaw with the "self-documenting code" theory. Yes, reading the code will tell you exactly what it is doing. However, the code is incapable of telling you what it's supposed to be doing.

I think it's safe to say that all bugs are caused when code is not doing what it's supposed to be doing :). So if we add some key comments to provide maintainers with enough information to know what a piece of code is supposed to be doing, then we have given them the ability to fix a whole lot of bugs.

That leaves us with the question of how many comments to put in. If you put in too many comments, things become tedious to maintain and the comments will inevitably be out of date with the code. If you put in too few, then they're not particularly useful.

I've found regular comments to be most useful in the following places:

1) A brief description at the top of a .h or .cpp file for a class explaining the purpose of the class. This helps give maintainers a quick overview without having to sift through all of the code.

2) A comment block before the implementation of a non-trivial function explaining the purpose of it and detailing its expected inputs, potential outputs, and any oddities to expect when calling the function. This saves future maintainers from having to decipher entire functions to figure these things out.

Other than that, I tend to comment anything that might appear confusing or odd to someone. For example: "This array is 1 based instead of 0 based because of blah blah".

Well written, well placed comments are invaluable. Bad comments are often worse than no comments. To me, lack of any comments at all indicates laziness and/or arrogance on the part of the author of the code. No matter how obvious it is to you what the code is doing or how fantastic your code is, it's a challenging task to come into a body of code cold and figure out what the heck is going on. Well done comments can make a world of difference getting someone up to speed on existing code.

查看更多
Deceive 欺骗
6楼-- · 2019-03-25 05:02

My approach:

Comments bridge the gap between context / real world and code. Therefore, each and every single line is commented, in correct English language.

I DO reject code that doesn't observe this rule in the strictest possible sense.

Usage of well formatted XML - comments is self-evident.

Sloppy commenting means sloppy code!

查看更多
唯我独甜
7楼-- · 2019-03-25 05:03

When programming in C, I'll use multi-line comments in header files to describe the API, eg parameters and return value of functions, configuration macros etc...

In source files, I'll stick to single-line comments which explain the purpose of non-self-evident pieces of code or to sub-section a function which can't be refactored to smaller ones in a sane way. Here's an example of my style of commenting in source files.

If you ever need more than a few lines of comments to explain what a given piece of code does, you should seriously consider if what you're doing can't be done in a better way...

查看更多
登录 后发表回答