- You're implementing something complex (like an algorithm)
- You're implementing something stupid (typically a workaround for something that could not be done in a more elegant way, and you want to explain why it can't be refactored)
If the code is well written it is also self explanatory. This can be done by structuring / formatting the code well, into methods, classes, packages - and naming these constructs in a reasonable way. Naming variables is obviously also very important - and be consistent!
In my opinion comments only clutters the code, and in most cases reduces readability. Like mentioned before you cannot always trust that the comments are up-to-date, but the code certainly will - so I believe time should be spent making the code readable instead.
"Look, there is what you intend and what you write" - those should be the same, there should be no in-between.
My primary language is Java by the way (about 10 years of experience).
I'll second that. I think comments are extremely useful for situations where the code isn't clear enough. Comments are also useful to explain why something was done a particular way when other ways might appear to be more obvious.
i.e. // unrolled this loop because this is a time critical method and the compiler isn't currently doing that for us.
My main argument against tons of comments is that they are likely to not match up to what the code actually does. No matter how vigilant the developers are there is 0% chance that the code will be out of sync with the code and a >0% chance the comments will be out of sync. If you feel the need to write comments for a block of code see if you can find a way to make the code easier to read before you try and solve the problem with a comment.
I agree, but unfortunately they're also necessary in circumstances, hopefully rare, when your ability to choose your own names is otherwise constrained for whatever reason - a configuration file, or a framework dictating conventions, for example. If you have have to do something complex, and there's absolutely, positively no way to explain it in code, then comments are appropriate. Otherwise, the impulse is misguided.
I agree with this, but I have to admit I have met many developers who have the same philosophy but can't code simple, readable code in the first place. Given how easy it is for people to overestimate their skill and how well they are building any one piece of software, I just default to writing sensible comments whenever possible.
There's an huge requirement for comments in C# that isn't needed in java - that of describing what exceptions a method may throw. This is probably also the place where comments are ignored most of the time too - I literally cannot count the number of times I've seen programmers failing to catch obvious exceptions, even in the framework libraries.
I've been writing code in some language or another for almost three decades. My headers, comments and READ_MEs usually end up helping me more than anyone else.
When you have multiple projects in muliple languages for tens or hundreds of clients over the years, the last thing you want to do is open a project or repository and see little or no documentation. And you don't want to have to figure out what/why the heck you did in 2007 and explain the project to coworkers.
I guarantee you that clients and coworkers will pick the worst optimal time to want revisions. And if I spend the time upfront to make it simple for a junior member of my team to take ownership of a project in the future, my life becomes better.
"Look, there is what you intend and what you write. Your bugs are in between the two."
Umm no. Bugs are usually
a) a misinterpreation of the requirements (no amount of comments are going to save you) or
b) a (hopefully) subtle error in the code - again - I don't see how a comment is going to help you unless the comment is practically pseudo-code which I (hope) nobody is advocating.
Anyone have an example of the typical type of bug that is easier to fix when there are comments around? I agree about commenting "non-obvious" code though - at least in terms of it's intentions. Not necessarily as a way to fix bugs, but to prevent the next programmer from removing something that looks superfluous because nobody can remember why it's there. Something like (totally made up):
"Assign the customer id as a prefix to the comment field; SAP expects the format of <customer_id>__<comment> during import".
Note that the following does not count as commenting your damn code:
// Get the account holder currency
$currency = $accountHolder->getCurrency();
Imagine several 10s of KLOCs where 99% of the comments are as worthless as this and most people are content with their efforts because they believe they are commenting thoroughly.
Personally I appreciate good "how" comments for algorithm implementations in C++, where the implementation in code isn't as clear as a (perhaps less efficient) pseudo-code version in the comments. "How" comments are just as valid as "why" comments, and the parent comment illustrates that "copy-comments giving no more information or intuition than the code" are worthless, which is why I don't have comments every 3-7 (not even every 20) lines like the submission suggests.
Why comments are important: they represent intention.
A reasonable complex method can have a wide variety of inputs which the author can't be expected to have tested across the entire range of values. For example, if you have six boolean inputs, you have 2^6=64 possible combinations.
If you have six integer inputs, you have roughly (4e9)^6=4e57 combinations, which is more than the number of atoms in the Earth.
Expressing your intention means that when you (or someone else) come back to the code to change it, you can at least have an awareness of whether the behaviour you are seeing is in line with what you intended. Because a bug might not even be a bug - in that code - but a misuse of a method for something it wasn't meant to do.
Intention is all well and good, but imprecise. It also is not accurate to suggest that what is written is what is intended. One of the best ways I know of to describe intent is with tests. Not only do well written tests describe exactly what is being done, but it also tests to enforce this. There is no mistake about what it expected and intended.
A comment, on the other hand, cannot be trusted. Ignoring the fact that it could simply be out of date and wrong, your interpretation of intent might not the same as the person writing it. A lot of this might be because you simply don't share the same context. After all, when this comment was written has a context beyond the location of the code.
There's no need to trust a comment, it simply tells you what the author was thinking, as best as s/he could express it. It's less imprecise than no comment at all. Suppose you have a very simple function that does something clear - reading the code you can tell what it does and how. And suppose that function is called from several hundred different contexts in the codebase, but one of those contexts causes an exception in your simple function.
You could "fix" it, with a code change. But what if your fix goes against the assumptions of some other context where the same function is called? A comment that describes what the function "should" do allows you to decide whether changing the function, or its caller, will be more in line with the design of the overall codebase. This is particularly true with mature codebases where thousands of tiny fixes and tweaks have accumulated over time. There's a corpus of learning about why the code ended up that way that even in-depth reading of individual functions might miss.
Tests are good, and to be encouraged. But using tests in place of comments is rather like answering a question with a question. Tests provide confidence, they do not provide understanding.
Of course, you could do an in-depth analysis of every function, in every context it's used, and how it interacts with its callers and callees. While you're doing that, the guys who commented their code will be moving onto the next challenge.
Nope. You need to comment every nonobvious decision, but if you write code the right way then the nonobvious decisions disappear. A well-written method doesn't need explanation, because it obviously couldn't have been written any other way.
One problem with this, is that it's probably subjective what nonobvious code actually is. Of course, it's subjective how much commenting is enough, as well. In my experience, projects where it has been decided that comments are not required, have ended up with uncommented and nonobvious code - the worst of both worlds.
This could perhaps been prevented given proper code review processes, that were not in place. However, in a project with varied skill level, I would personally prefer advocating both commenting and obvious code, since the end result will probably be something inbetween.
I'd really like this to be reality.. but in my world, there are too many programmers who don't write code "the right way". like > %80. For the great programmers sure ok, its obvious, but for the rest of them.. no.. you're not the coding genius you think you are.. please comment your code. Don't be tricky, clever, smart.. or self-documenting. Comment. period.
A nice example which expresses the bulk of the issue: Comments are largely there to compensate for the lack of information held in the type system. Adding comments which just reiterate what is said in the function signature is redundant and not worth the time.
Of course, this doesn't apply to all comments - but specifically those insane policies where you're required to write a description of every method, argument and return type.
The more powerful the type system, the less necessary comments become. If you take a dependent type system for example, or some code contracts with explicit preconditions, you no longer need to specify the valid range of values for a given function in some silly comments which will fall on deaf ears in the majority of cases anyway. The programmer will be stopped and forced to read it, rather than waiting until runtime to discover the correct behavior, if at all.
// NOTE: Workaround for a bug in the framework
// foo will crash if you foo before bar.
// Here we bar with a null value, which prevents the crash
bar(NULL);
Except In my opinion he gets it very wrong. His comment free code doesn't include the the string "Newton-Raphson" anywhere, making it non-trivial for anyone not familiar with the code to work out what is going on.
Secondly, and more importantly, he never explains why he is using Newton-Raphson to approximate the square root. If I was handed this in some code I was to maintain I would really really like to know that.
Note the he does say the following:
When you've rewritten, refactored, and rearchitected your code a dozen times to make it easy for your fellow developers to read and understand -- when you can't possibly imagine any conceivable way your code could be changed to become more straightforward and obvious -- then, and only then, should you feel compelled to add a comment explaining what your code does.
Every comment is also a liability, especially in light of the fact that the comment may, over time, drift away from the code. I sometimes wish I had an IDE that would color nearby comments red (and prevent commits) when code changes.
Which is to say, make comments where necessary, but own the liability, and strive to remove comments you find by making the code more obvious, just as you would strive to remove code to make it simpler.
I used to work with someone who would start writing a function or module by writing their code as comments.
# First we iterate over the directory and get a list of files to process
...
# Then we process them
This "pseudo-code" would then be filled in by the actual source code ei intended to write. And once ei was done the comments would stay in and be checked in for code review.
Nothing was more tedious to read. It's like having a narrator tell you exactly what each character is going to say right before they say it. It is quite maddening to this reader and I had to constantly review this sort of code.
I had to politely approach the person writing this code and explain this to them. Comments are not for describing what can already be read. One's code should be written in such a way as to inform a programmer maintaining the code to its purpose and utility. That means short, single-purpose functions, conventions, idioms, and all of that. But it also means that comments should only be used when you're going against convention or doing something hack-ish on purpose.
I saw fewer lines of comments until a fresh, new young team member joined...
I do this, and I'm a senior dev. I find it an absolute God-send when I come back to the code months or years afterwards.
I am much, much faster at parsing and reading English than I am at code. When I'm coming back to some code for maintenance work, I am not normally trying to understand code deeply, I am usually trying to get a quick overview of it, and then locate a specific thing it's doing, to parse it more deeply.
Comments like this allow a skim read for locating what you're after, and - as you identified - normally come in as I'm detailing the process, which means, doubleplusgood, you also get to see what I was thinking as I was writing the original code.
> One's code should be written in such a way as to inform a programmer maintaining the code to its purpose and utility
Almost. But you forgot "as quickly as possible".
> But it also means that comments should only be used when you're going against convention or doing something hack-ish on purpose.
I suggest that with experience, especially experience of being the curmudgeonly old senior dev on very mixed ability teams, with codebases sometimes a decade old, where the code is occasionally insane, you will start to be thankful of all clues the code can possible offer up as to why people do what they do.
I read tonnes of code. I've formed my opinion by reading and reviewing tonnes of code. I'm cautious about jumping to conclusions.
In my experience the kind of code that requires comments to act as "guideposts," (if I've correctly interpreted your meaning) is suffering from symptoms of a larger problem: poor design. When I read code that comes from people who use this style I often find that their functions go on for ~70 LOC, use at least 3 levels of nesting, and are littered with comments to explain what is going on.
More often than not I was able to show them that they could break these procedures out into compose-able functions and drop the comments. With the right data-structures they could avoid excessive loops and conditionals. And with the right unit tests if they ever needed to change the implementation of a function they would know right away if they broke something. Suddenly they didn't need so many comments because their functions were < 10 LOC and self-explanatory -- the name of the function gave its meaning and the higher-level code read more like an explanation of the process without all of the details of how the machine should perform it.
That, of course, is the best case scenario. I've worked on a gnarly C++ web application that was more than a decade old and survived several attempts to port and extend it with Python. But you can deal with that too. Just try not to touch the legacy code. ;)
It's better to make a mistake in your thought process that can be caught by reading plain english than to write the code and realise the logic is wrong. However, I agree that comments that are completely banal should be removed in place of more interesting ones about the design decisions, performance characteristics, etc. (I however do start by writing comments explaining exactly the code I am about to create as I like to spot higher-level problems as early as possible.)
>> I saw fewer lines of comments until a fresh, new young team member joined
However literate programming isn't about commenting your source. It's about explaining your program in plain human language and presenting it in an almost essay style. A special program is run on your "literate" source which translates it to a set of source files that your compiler understands. It is not about writing verbose and excessive comments in your source code.
I don't mind if your approach is to write out pseudo-code or comments or what-have-you. My problem was that checking this stuff into the code-base wasn't a good idea. I don't suspect I changed the minds of the people I had to work with but they did remove the excess comments from the code before checking it in. That made reviewing their code much easier.
Comments can't guarantee to represent what the codes does always. "Don't be lazy" is a fine argument, but it takes one time that you are under pressure to ship right away and you don't comment.
Tests, on the other hand will keep failing until they describe the updated version of the code.
We should strive to make code obvious, when it's not obvious, then you should comment, or better: simplify your code.
There's usually a large amount of comments and metadata relating to code that isn't present in the source files themselves, but in an external database:
git blame path/to/file.txt
I think this is one of the most underused tools in software development! I wish more editors had features like "show me the history of this class/function" etc.
I also disagree. Commenting is something I do when I'm being lazy - too lazy to make the intent of the code obvious. Sadly, this is also the impression I get when I see comments written by other developers. (That said, method-level documentation is still something I'm on the fence about.)
"Every 3 to 7 lines of code you'll find some amount of editorializing. Maybe every few hundred lines you'll find a good joke too."
I think there's the issue. In applications I write, every 3-7 lines of code is refactored into a method that is named exactly what it does, and every few hundred lines of code (usually much less) is in a separate file and class named on what he does. Broken out like that, there's not many places to put a comment that would be of any use.
But not broken out like that, of course you're going to need comments. But I think you'll find that comments aren't even enough.
"I know what the code says. But tell me the intent."
I think unit tests and expressive code work much better to achieve this goal.
So many comments already... Well, that's to be expected.
I agree with OP wholeheartedly, but I think he misses one obvious thing and that is the fact that commenting code is hard. Very, very hard, laborious and easy to get wrong. It hard even for people who are used to writing prose, like heavy bloggers for example. It's made even harder if you don't write in your native language, and "even harder" here means "almost impossible for many".
Unlike many programmers I enjoy writing, which should be visible to anyone who sees my comments here. I have quite a lot of background in writing various texts, from short stories to essays. Yet I find commenting - or rather - writing good comments in code very difficult. I think I can do this, I got praised for the comments at one time or another, mainly for their clarity (instead of sheer volume) which makes me extremely proud, but the fact is that I spend almost as much time on commenting the code as on writing it... Sometimes I write comments up front along with tests, to clarify my thoughts, sometimes I write them after coding something, but that does not change the difficulty at all.
I think the art of commenting code - and it is an art, no doubt about it - is comparable with debugging. As we all know, debugging something is twice as hard as coding it, so - by definition - if you code something to be as clever as you can you won't be able to debug it. Nor comment it properly.
And many of comments such as "I'm against commenting code" stems from this, I think - in many cases we're forced (in school, mostly) to code near the limit of our ability and then we're forced to comment; of course those comments are crap, but that's what we see for a very long time. Then we get used to it, we kind of expect comments to suck, and we think that they are a waste of time.
Not so. They are just very, very hard to master and there are very few people who would even try to teach about them. We can say whatever we want, but it won't change anything. We need to find those who really can write good comments and make them teach others...
After all this I have to admit that I doubt it's possible. Don Knuth tried with his "literate programming" idea and failed miserably. Among 25 programmers at my current work just one even knew the term, but didn't know any specifics, while all of them know who Knuth was. I don't mean to say it's hopeless... But it certainly seems like that to me.
You should comment your code if and only if your algorithms has special pre-conditions and post-conditions otherwise your choice of variables name should make your code speak by itself... exemple of pre condition: your algorithm don't handle non latin word ... exemple of post condition , your algorithm only return a specific format like aa-bb-cc ...
or like my teacher said use your common sense, make your code as clear as possible.. I should understand it without you ...
ok, so i wrote some code yesterday. i didn't write it expecting anyone to read it (i mean, not critically on hn), and it's not as good as i would like, but it has no comments (apart from at the top of the file explaining how to use the program).
so, people who are saying "just comment it" - what would make a big difference to this code?
First of all, I have written only very little Python in my lifetime.
Second, I thought the code was pretty clear except for the refresh function in the TextLine and BarLine classes. The only other thing that could use a comment was the track_data function to show what the string looks like that is being returned.
PRESETS could use a brief explanation. Even after reading all of the code I'm not entirely clear on what it's being used for, and there's no hints to its purpose where it first appears.
thanks for the comments guys. i often work alone so it was interesting to check whether my standards match others. i agree on the points identified as being the weaker parts, and i'll try fixing things (not sure if that means re-writing or adding comments) when i have a moment.
[if this were paid work i hope i would have done something a little better, but that's easy to say...]
but also, in the context of this thread, maybe this shows that code doesn't need comments as terribly as some people seem to think.
my own opinion is that generally if you need a comment you should try to improve the code first, but that sometimes they can be useful. unfortunately that's a rather pragmatic approach that doesn't make for great blog posts or discussion flame wars...
If the author had simply chosen a few examples of good commenting in code and exhibited them, then he wouldn't have had to write this article explaining his point..or would he?
This is a sign that your code is poor, and comments aren't going to help poor code. When you need to comment to overcome poor code, that's a sign your code needs help, not your comments. Thinking comments are going to solve this is a losing game. If this is the way you think, then you'll continue focusing on propping up poor code with comments.
Comments are inherently dangerous. Not because commenting is bad, but because comments are inaccurate. When you write a comment about a block of code, the comment will never be as precise as the code. You'll write about the intent of the code, but even the intent is unclear. The reason for this is with the language we use to write comments. These comments rely on context of the person writing them. And writing is not easy. Describing a block of code that will determine the longitude and latitude is difficult. Do you describe how it does this, the reason it's doing this? Do you talk about how it accomplishes this? Why you are doing it this way? What's important.
For example, take this bit of advice about "good comments":
> A comment should describe the why or the goal, not the how.
So, a good comment would be as follows:
// We accept a search string from the user and transform it
// into a latitude and longitude from the location service.
// We do this because the user knows about where they are, but
// we don't have access to their GPS data at the time, so this
// is a great way to get local data at some level
So, this explains "Why" we are doing this, "what" we are doing, and the goal. However, nothing here is special to a comment over well written code,
public Location getLatLongFromUserLocationSearch( String search );
That does far more, and is more accurate, then the original block of text. More importantly, that original block of text is fundamentally flawed: it's blatantly inaccurate. It also encourages laziness. After all, if your poorly written code is resolved by simply adding a comment, instead of tackling the more challenging part of writing quality code, you take the simple way out of adding in a, most likely, poorly written comment.
> Look, there is what you intend and what you write.
This remark is amusing. Between the two, the chance of a comment being wrong is greater than that of the code. The code is at least tested at some level. The comment is not.
> Don't be lazy
This is an article focusing on writing comments well to cover up for confusing code? The assumption here is that it's easier to write comments well. I'm sorry, but if you can't write the code cleanly in the first place, how are you going to effectively write a comment that will clear things up.
> You're a Journeyman
Damn right, and I know that there are far better avenues than writing comments in code to accomplish that. On top of this, the example is absurd, as he's suggesting not limiting what your comment includes to what and how, but also why: "Tell them why you choose to use a Tuple in this case."
> So you type 40 - 60 wpm. So then tell me again why aren't you writing comments while you blaze through your code?
Oh, the travesty. To equate typing speed with quality. And make no mistake, that's what is being done here. Somehow, typing speed is the issue. It's akin to relating line count to performance. Listen, typing speed isn't the issue. It's quality, and quality takes time. Writing quality code is not defined by your typing speed. Neither is writing quality comments. It doesn't take a long time to write quality comments because you lack typing speed, but because writing clear comments is hard work.
> You're going to get old
If you weren't clear that an ego the size of Jupiter was writing this post, this section will slam the point home.
First, let's get this out of the way:
"I've been doing this for a while, probably before you entered middle school."
Your age does not qualify you. Bringing it up again and again only means it's the best qualification you've got. Wisdom isn't about age, though age gives you more opportunities for obtaining wisdom.
As for getting older, there are far better mechanisms for ensuring that you know what the intent of the code is, from both a business sense, and from a code sense.
Honestly, the biggest warning to relying on comments to resolve deficiencies in other areas is this article itself. It's poorly written, confusing, and even contradicts itself.
In the end, it's some of the same tired advice presented in a brash way. This brash method, employing vulgarity and rudeness, fails. "Comment your damn code because I said so and I'm old and that makes me right" is essentially what it amounts to.
I'm harsh, James, because your article is harsh. It preaches writing comments, and does so in poorly written English.
In the end, commenting your code is the worst thing you can do.
Commenting your code well, however, is not. But commenting your code well is a challenge. It's not easy, and should not be seen as trivial.
Well written code takes longer than 30 seconds to write. Well written comments take longer as well. And well written comments in well written code are not added every 3 to 7 lines.
"The assumption here is that it's easier to write comments well."
And this assumption is clearly wrong. Just wanted to underline this.
"It's quality, and quality takes time."
...and skill!
"because writing clear comments is hard work"
"But commenting your code well is a challenge. It's not easy, and should not be seen as trivial."
"Well written comments take longer as well."
So true. I'm glad there's someone beside me who thinks that.
I cannot agree with you more. I didn't pay attention to giant ego of OP and I'm not qualified to measure how bad his English is (mine is certainly worse), but now that I think about it you're right - I still do believe that the author meant no harm, but the tone that he used won't help his message get across at all. :(
> I still do believe that the author meant no harm
His intentions were good, his delivery was poor. Ironically, the article itself makes for a great argument on why comments (here on HN) can be good, if you consider the article the code itself.
Of course, I'd argue that the comments here represent code review more than anything else.
OP make a good point that comments help to make your intent more clear, while the code itself just explains what the program does. Very good reason to have some comments here and there.
But I'm with Toshiro - test your damn code! Testing first brings all the benefits of commenting and more:
Tests help document and clarify your intent. They convey your assumptions, expectations, and show you exactly how methods are expected to behave when you run the test.
3 months later when you're adding new features, a failing test tells you that you introduced a bug before you ever run the new code.
That said, comments have a place in the tests themselves. Much better than scattering comments all around the code base.
The other place for comments is in the version control. Make small, frequent commits and set up your version control so that it forces you to comment each time.
When you're doing these things, comments in other parts of the code are just redundant and noisy.
Until someone comes to do major rework and your tests take ten times longer to change than the code. It happens - a lot. Badly structured tests are worse than no tests to the extent that it's often cheaper to throw the lot away and write new tests - turning what should have been a simple "change the class hierarchy without changing the public interface" into "oh god every single test relied on the detail of the class hierarchy". No, they SHOULDN'T have. But they DID. And I get to fix it. Again. A particular anti-pattern I am observing right now is the "immutable interface, mutable implementation" approach. Every single test in 6 different sub-projects appears to want to create "special snowflakes" for testing, but was written to mutate an implementation which no longer exists. Days of extra work needed to figure out what the intent of the test was (no comments, because tests are self documenting, right? Sure they are.) and then re-write it using builder interfaces in the hope that this will save some poor sod (probably me) the trouble the second/third/fourth rewrite.
Be a better damn developer. Tests don't deserve cut and paste hell any more than your actual production does.
- You're implementing something complex (like an algorithm)
- You're implementing something stupid (typically a workaround for something that could not be done in a more elegant way, and you want to explain why it can't be refactored)
If the code is well written it is also self explanatory. This can be done by structuring / formatting the code well, into methods, classes, packages - and naming these constructs in a reasonable way. Naming variables is obviously also very important - and be consistent!
In my opinion comments only clutters the code, and in most cases reduces readability. Like mentioned before you cannot always trust that the comments are up-to-date, but the code certainly will - so I believe time should be spent making the code readable instead. "Look, there is what you intend and what you write" - those should be the same, there should be no in-between.
My primary language is Java by the way (about 10 years of experience).