5 ms·
My one addition to this would be: comment what you intent the code to accomplish not what it actually does. I can see what code does, it written there, in code
by aequitas 8y ago
My one addition to this would be: comment what you intent the code to accomplish not what it actually does.
I can see what code does, it written there, in code! I want to know what its purpose is so I can decide if I have to remove/refactor/fix it.
Often code doesn't do what was intended (a bug) and by only commenting what it does the bug transpires into the documentation as well.
Compare "// loop over array of numbers and add them together" with "// compute sum of all product prices in cart".
The first is only helpful if you are explaining a language to someone or are not confident about the language. The second tells the importance of this piece of code in the greater whole.
- v3gas 8y agoAnd the second should, imo, not be a comment, but rather a function name.
- nickjj 8y agoThe worst is when that second comment isn't there and you're left wondering what's going on, which leads back to naming things well. Compare: findNeedles(haystack, needlesList) [insert a few nested loops which are hard to follow unless you run the program to see what it does] vs: countWordsInString(str, wordsList) [same code as above]
- aequitas 8y agoThe problem with function names is that there are other factors that decide them. Conciseness of code being one. And as I commented below. At the time you write code it might not be obvious it will turn into a function. With a proper comment that decision can more easy be made later on.
- mannykannot 8y agoThat only works in simple cases. Most cases are simple, but the ones that matter most are the ones that are not. There is sometimes a great deal that can usefully said, about what a function is for, that is only apparent in the context of its use. If the purpose of a() is accomplished by calling a1(), a2() and a3(), it would not be unusual for the purpose of a2(), for example, to only be understandable in the way a1(), a2() and a3() work together to satisfy the purpose of a(). If the only words you are allowed to write are the names of the functions, there is nowhere to document this interaction (especially if the name of a() is supposed to say what it does, not how it works.) The more you break down a solution into functions, the more the satisfaction of the purpose of the program becomes a consequence of how the functions interact. For an example, look at the comments to the function checkListProperties in christophilus' SQLite example [1], and consider how you would convey the same information through function naming. Then look me in the eye and tell me that's the way you write code. [1] https://www.sqlite.org/src/artifact/9711a7575036f0d3 https://www.sqlite.org/src/artifact/9711a7575036f0d3
- dsego 8y agoAnd then often that comment means that you can extract the code it describe into a separate function of the same name, e.g. price_sum(products).
- aequitas 8y agoThat is the choice you often make later on. But might not always be obvious at that time, otherwise leading to overoptimizing everything in functions.
- christophilus 8y agoAfter 20 years as a software engineer, I've started commenting heavily. I used to comment sparingly. What made me change was a combination of reading the SQLite and Redis codebases and inheriting two biggish projects (one Rails, and one JS) which had no comments. Reading through code that looks like this[0] is so much nicer than reading through code that looks like this[1]. [0] https://www.sqlite.org/src/artifact/9711a7575036f0d3 https://www.sqlite.org/src/artifact/9711a7575036f0d3 [1] https://github.com/mysql/mysql-server/blob/b93c1661d689c8b7decc7563ba15f6ed140a4eb6/plugin/keyring/buffer.cc https://github.com/mysql/mysql-server/blob/b93c1661d689c8b7d...
- dep_b 8y agoThe problem is there's not just one type of code. Shared low-level code needs much more comments as shuffling a bunch of words through memory often is a bit abstract and you don't get the "why" by just looking at it, while writing business code that basically glues the UI to the DB using a lot of frameworks for the ugly parts can (and should) read like English. I would suggest to use commenting as soon as you're doing something that's not immediately obvious to the reader, which can be all of the time or almost never depending on what you're doing. If would like to see some examples of Rails or JS code that needs comments according to you to have a better discussion about it.
- anyzen 8y agoI made an opposite journey. While working in C and Java I commented heavily, but in Python I prefer to just leave a comment here and there if I'm not sure the reason for the code and its intent are clear - but at the same time a comment is also a powerful signal for me to rethink that piece of code and make it more obvious. I find both of your examples readable to about the same level; MySQL one because the naming is helpful (`number_of_bytes_read_from_buffer`) and SQLite one because of the comments - I would be lost without them. For example, why is a function that does "Release the STATIC_MASTER mutex" called "leaveMutex"? On the other hand, SQLite comments explain much more about how the code is used, what assumptions are made, so this is really a bonus.
- curun1r 8y agoEven your second version of the comment is too what and not enough why. What comments are worse than no comments. They take up valuable space and become a liability if they're not kept in lock-step with the actual implementation. As I've matured as a programmer, I've found that commenting everything is actually an anti-pattern. Every line of code is a liability that contributes to maintenance costs, even comments. Just as you should think about every executable line in your source code, you should put the same thought into all non-executable lines. I prefer to comment judiciously and try to write my thought process and anything that's likely to be confusing to help future developers understand the overall approach and intent of the code without trying to lay out the intent of every single line. Lines that are particularly complex get a comment, but anything simple stays uncommented, especially if it's idiomatic for the language. If, to take your example, the code were: let cartTotal = products.reduce(0, (total, product) => { total + product.price }); It probably does not need the comment you've listed. The names alone convey intent. If, however, you're were doing something like integer math, you would put a comment to the effect of // cartTotal is computed in cents to avoid floating point math/rounding // and must be divided by 100 to get the dollar amount. That conveys information that is very difficult to extract from the code or the variable names. I've also realized that, by far, the best comments I can leave are unit tests. They never become incorrect because they're forced to update with the code. When I'm trying to learn a new code base, I always start by running the tests and, if they pass, reading the tests before I read the code they test. There is no better way of understanding what use cases a developer thought were most important than the automated tests s/he felt were necessary. I love that new languages like Rust give developers the ability to combine documentation and tests and I hope many more languages follow that example. The second best documentation are function/method/class/object/struct names. It's very important to get them right because they not only provide meaningful information in the place they're defined, they also provide useful information wherever they're used. Try to avoid the following: /** * Helpful comment */ class UnhelpfulName ... The reason this is such a big problem is that it requires the developer or the IDE to find the comment whenever the name is referenced elsewhere in the source code. Names permeate throughout the codebase much better than comments. And if you lean too heavily on comments to provide meaning that the names do not, you end up having to write the same comments in many locations.
- pc86 8y agoComments should never tell you what the code does, they should tell you why it does it. If you have a method named "SumCart" and it's clear that it loops through the products in the cart and returns the sum of the prices, a comment "// compute sum of all product prices in cart" is absolutely useless. All it does is take up space. What's not useless is a comment like "// Ignoring tax rates for sum because some products are taxes differently" - Comment the why, the business decisions, rules, technical debt, etc that's not immediately relevant when looking at that one method. Anything else is clutter.
- aequitas 8y agoThe comment example tells what I intend the code to do, in this case provide the sum. Not how it does it. Maybe my example was to trivial to justify a comment I agree with that, a proper function name would have sufficed. The main point I'm getting at is the intention. All coding is is a translation of your intention to something machine executable. And often mistakes are made in that. That's why I comment to keep the intention close to the implementation.