I find that the commonly touted opinion that comments should only reflect why, and avoid all duplication; is misguided. The only places where I will elaborate on why is where I can see obvious room for improvement but I'm still waiting for the bigger picture to stabilize, or I'm adding a dependency that I'm not really happy with. Otherwise my comments mostly express the intent of the code in regular prose and have to be updated with the code.
I'd say then that your comments [regarding intent] are overly specific.
If updating the code block results in code with a different intent... you're not updating it, you're replacing it, and should take out the original comment with the original code.
If I have a code block to maintain data synchronization with a a server - that's the intent; if the code is updated from long-polling to websockets, the intent hasn't changed.
If your comments just say what the code does, they're redundant and unnecessary. Good comments explain things the code can't, like why you chose a particular algo, or why some piece of code needs to exist. Most code when written well requires no comments. Comments like yours, that repeat what the code does, I simply delete.
So where would you document the "why" then? This is often the question I find most difficult to answer when reviewing code (including my own) -- after all, I can ferret out the what from the code.
If we are speaking of API documentation (i.e. function or module documentation): The "why" can't be explained here. It's at the caller side.
There are more rare cases where it's reasonable to document the implementation of a function because there's a particularly tricky section of code -- and documenting the "why" makes more sense to me here.
The biggest problem I have with comments is that they quickly fall out of sync with the code. The code gets updated but the comments stay the same. Now you have a situation worse than no comments: misleading comments.
It sometimes happens with self-documenting code too, but only when someone refactors enough of the code so that the class or method no longer matches the original name.
I hear this all the time as to why comments are "bad" (and I'm not suggesting that's what _you_ are saying, btw). Comments need to be kept up-to-date with code changes. The same way unit tests are kept up-to-date, and everything else around your code is. Comments are no exception.
It's a matter of incentives. Business folks don't care about comments unless they have a dev background. Your options are then to focus on the incentives present in the situation, or materially harm your own life and well-being by working extra hours to make up for your management's inability to manage.
I hate this excuse. It seems like every lazy habit of programmers gets pushed onto the "business folks".
Just because business folks don't know how to value certain developer practices doesn't let you off the hook. Just do what you have to do and if it takes longer because you had to learn how to do it, then it takes longer.
Let the business folks tell you when it's taking too long to deliver features.
But it does. It depends on the organization, but there are groups where chugging coffee, talking a lot, and pumping out dozens of half-working features by coding like a drunk cowboy will get you promoted and recognized as a team player, while pushing back to take time and do things right will have you reprimanded. Many such cases out there.
My point is that you shouldn't push back. Just do things the way they need to be done, and it takes as long as it takes.
A manager looks at a programmer bringing up something like unit testing as "why the fuck is he asking me about this, it's his job? Obviously because he's asking me it's outside of his professional ken, so that means it's going to take absolutely forever." Out loud he'll just say, "Can you just get the feature done?"
Don't ask, just do it. It takes as long as it takes. If they ask, just say it's not done yet.
This generally won't work for straight forward game theoretic reasons. Boss thinks you're slow->boss brings on h1b consultant willing to pump out spaghetti code and toady up to him->you looking for a new job. Organizations get what they ask for
Being good at your job won't magically make you fast at fixing up other people's spaghetti code. It won't let you ship 3 working features faster than someone else who's also "good" at their job ship 6 mostly broken features. It won't convince your manager that the former is actually getting more work done than the latter, and won't prevent them from thinking the first guy is slow and the second guy is fast.
But for what it's worth, I agree with you in that I'm still on the hook. Either to help educate my manager, or to pick managers who already understand this stuff.
In my company, the business folks have no idea what the code looks like or whether or not there are comments.
All they care about is that the code works, and that features can be delivered on time.
That second part "delivered on time" includes maintaining the comments along with the code since it makes the code more readable, and eases future changes. If Management doesn't give you time to write maintainable code (which includes keeping comments in sync with the code), then you may as well start looking for a new job because the technical debt is going to pile up and it's going to get harder and harder to meet deadlines.
They don't care about comments, per se, but they probably care about whether someone else can easily work on the code. I'd think (hope) most technical managers are going to encourage some sort of team review of the code and not get all the way into the weeds about what specific issues in the code review need attention.
Would be cool to have a utility that embeds a hash of the function in the comments, and could check automatically. So if a function changes and hash doesn't the user would be alerted.
I find that I have this problem with my own code. Ridiculous, but it happens.
The thing is, if somebody forgets to update a unit test, it immediately becomes obvious. If somebody forgets to update a comment, it's very easy for no-one to notice until it's much too late. There's no way to automate that check.
In terms of developer resources, the act of doing updating the comments is cheap, but the act of making sure it gets done (in a systematic way) is comparatively expensive.
But it's not immediately obvious if someone changes something that isn't covered by a unit test. Or forgets to create a unit test. Does that mean we should just abandon writing unit tests altogether?
You could always use a tool like Danger (http://danger.systems/) to inspect your code and warn you when code has been updated, but comments nearby have not been.
> But it's not immediately obvious if someone changes something that isn't covered by a unit test. Or forgets to create a unit test.
This is what code coverage analysis/metrics try to address.
> You could always use a tool like Danger (http://danger.systems/) to inspect your code and warn you when code has been updated, but comments nearby have not been.
I'd worry about tuning out said warnings after too many false positives. Comments regular enough to not generate too many false positives can generally be turned into real syntax of some description.
So add comments to your code review process. This really isn't hard.
For example: python functions shall have a docstring unless trivial. For external api functions on a class, there must be at least one example. etc etc. Plus, this makes working in ipython really nice!
I usually apply something like this except only for public methods; I figure if you're digging around the private methods you probably need to look closely anyways.
The danger of stale comments is, I feel, overblown.
First, other developers know that comments can grow stale, so they're unlikely to treat them as sacrosanct, although I admit to falling into that trap.
More importantly, most of the types of comments that Eric recommends can drift out of sync with the code and still be useful. Why is this code here? What happened previously that is no longer in the code? What tradeoffs have been chosen?
> The danger of stale comments is, I feel, overblown.
Yes, because they should be, and are, largely ignored. Of course, deleting them is better than ignoring and not having them in the first place is better than deleting.
Code doesn't depend on variable/function names either. Yet you don't argue they fall out of sync, you simply update them. And this should be done for comments, too.
Code does depend on variable/function names. When you change the name at the definition, your code fails to compile until you also change the name at each usage.
This is not true of comments.
If we could make outdated comments produce compilation errors, we would live in a wonderful world :)
But it could. With C++ at least you can get your build to break on some comment errors. If you enable Clang's pedantic warnings, or if you setup Doxygen to emit warnings in the same format as your compiler and incorporate Doxygen execution directly into your build, you can get errors and warnings on bad comments.
Doxygen supports documenting function parameters, C++ template parameters, return values then Doxygen and Clang can tell if the name listed for some of those things doesn't match the actual code or if a certain kinds of comments are missing. This won't tell you the documentation is wrong, but it would stop you from adding or removing a function parameters while ignoring documentation comments entirely.
If you want to go crazy you can write Clang plugins using LibTooling and run and code you want and analyze the comments any way you choose.
> Code does depend on variable/function names. When you change the name at the definition, your code fails to compile until you also change the name at each usage.
Depends what language you are working in; in some it won't fail until runtime.
What I was saying that choice of identifier of the variables/function does not matter for the functionality, as long as they all refer consistently to the same thing. Take code obfuscated by replacing variable names, for instance. People don't argue we should run the code through such obfuscator out of worry that the identifiers can change meaning through code changes.
> If we could make outdated comments produce compilation errors, we would live in a wonderful world
It is impossible. The whole point of having comments (and also identifiers) is to tie the code to things that are not formally described. If we would formally describe them, they would become the code.
You could, at best, mark identifiers in comments (and what their refer to), and then you could use this to hint at comments that need to be updated (as somebody else mentioned). But it will never be a perfect process, because there will always be a boundary between formal and informal.
Counter example: method findSomethingByParam1(param1) was changed to findSomethingByParam1(param1, param2). Seeing such method name in the call stack can be highly misleading.
It seems to me this is more of a knowledge issue or even a code/discoverability issue.
The closer a piece of documentation is to the code the more likely it is to be updated. External manuals always become stale and comments in C headers are more likely to be stale than comments next to the implementation in C source files (or in any language that doesn't even have that distinction). Comments directly next to complex formulae or other technical BS are most likely to be correct.
Some learn that then suggest getting rid of all comments or putting comments throughout all the code, but if we look at it another can can infer that some of it is code structure problems. A 2k line class with 200+ line methods with comments at the beginning of each method is more likely to have stale comments that any number of tiny classes with 10 line methods. Then comments on a 10 line method are more likely to be read too, because they need to describe less. Ideally they just add the "why" to the "what" the method's name provides. If the whole method and all the comments fit on the same screen then the dev ignoring it must be truly lazy.
If you update code without updating the comments and it gets past review you have bigger problems than them being misleading. Good comments are dependent on good developers.
I treat the comments in my code as notes... things future developers will need to know, TODO's, occasionally why I'm doing things a certain way, or other things that may be forgotten. I try to make the code as readable as possible so comments aren't needed. If you really want the documentation, look at the tests. My test descriptions describe what the code should be doing. The actual tests describe the API. Then there's actual documentation. This tends to cover more high level stuff. If the code provides an API others will be using then I'll provide documentation on how to consume it, otherwise my tests describe the API.
All of that being said, I'm not dogmatic about any of the above. I'd prefer my code to be self-documenting, but I understand it isn't always for any number of reasons.
Usually the people who cannot write good code love to write comments because they somehow feel it makes the code better. But they cannot write good comments either. Then everything is horrible. Code is really complex and hard to understand and the comments just make it worse. They might be out of sync or just erroneous.
I'm witnessing this currently with the code base I'm maintaining.
Well, the point is that people who write good, clean code don't need to comment their code extensively. They don't need to continuously explain why they did some horrible hack or some trivialities because their code is well structured and very easy to understand based on other good software development practices. They don't write the requirements of their functions as code comments, rather they write unit tests that document the requirements etc.
I think this ignores the idea that code also has context to it, and that comments even in elegant code are useful not for documenting how a bit of code works, but why that particular thing was done.
I often work with code bases developed in academic circles. I.e. written by non-c.s. students. Of course they are not experienced programmers, how can they be, it's often their first real software work.
There is no professional code review, the code is sometimes beyond ugly, fragile. Bugs get fixed by the next generation... I just ignore all comments.
Again, it's not their fault, it is a given just from the situation. But in this situation, it's much better to teach them to write readable code first. And not to trust any comment already in the code.
> Explaining previous approaches that didn’t work; explaining trade offs in the current implementation; marking possible improvements (TODOs) in the code; anything else you’d like to communicate with someone reading or developing the code
To me, those are the functions of commit messages, not code comments.
Of course, a "proper" IDE (and I don't know of any) would give you the context of the commit messages "impinging upon" any given line/block. Maybe something like Light Table (whatever happened to that?) could be configured to do this.
> Presenting an example usage of the function and example output
And that's what (formalized) docs are for. You can certainly generate those from docstring-style comments, if you like, but personally I feel like they get it the way of editing the code itself, and would be better kept in separate files.
(Consider: would you put the gettext translation table for a string, inline inside the source file that contains said string? The arguments are the same, I think.)
Eh, that depends totally on the development culture. I do it all the time. Getting the history over time for a specific region is extremely nice when a piece of code is to be understood.
For the emacs users: vc-region-history is the best part of emacs 25. I totally consider it nice enough to motivate people to compile 25 by yourself if your distro doesn't provide it yet.
I feel like the most consideration that is ever spent reading a particular line of code, happens during the code review for the PR that introduces that code. When you're doing a code review, you read new code at the same time that you read the commit messages. The commit messages should explain+justify the code they commit. Heck, half the reason you can break commits down into little semantic pieces with tools like `git add -p` is so you can explain/justify each piece separately.
Really, rather than what I said above, it might be better if ever line of code were just always put in context of the PR+code review that allowed it to enter the codebase. Instead of git-blame(1), github-blame(1).
Self documenting code is not about the "how", it's about the "what". Ex: A method name should be FilterOutOddNumbers(). Not MapModulo2Predicate().
Indeed not everything can be expressed in methods and variable names etc and so comments can be helpful occasionally. But the focus must be on clearly written code with comments as an exception, not a rule.
As for SDC being myopic, I beg to differ. Code (and contents) is for developers and machines. End users and API consumers should have documents (hence documentation) available to them for purposes of tutorials, user guides and references.
Aside from "why", or explaining overly clever one-liners, the kind of comments I always find necessary are those providing before/after example of data during a transformation; and example strings w/ resulting capture groups for regular expressions.
Example:
# "tag1,tag2,tag3:val" => tags: [tag1, tag2], metadata: [tag3:val]
# fun one-liner goes here
No. Why make myself or another developer find an entirely separate file in order to comprehend a line (or three) of code? Why leave in a line of code that is all but incomprehensible without an example or explanation? Why provide a paragraph of explanation when a single line of example data will be more informative? Why further decouple the "documentation" from the code itself?
Yes, you want test cases, and that's where you also put all the weird edge case conditionals; but, it's not like you're going to copy the actual line(s) of code into the test case, so you'd either need to temporarily copy the code (or the data samples) to be adjacent, or open side-by-side editor panes, or what have... All of this is more complicated than an example.
But what about sample data that doesn't fit on one line? Then either your sample data is too complex, or this method is unsuited to your situation.
There are guidelines for maximally legible code. There are no rules. If you follow rules, someday, you will encounter a situation where the rules force you to produce sub-optimal work. "Simply" strive to write legible code, and you will succeed. Strive to follow rules, and you will succeed at following the rules; and maybe you'll succeed at writing legible code.
I think the Uncle Bob quote is good: "Code comments are not the Schindler's List. They're not pure good."
If a line of code has a comment attached to it, the reader needs to understand both the code and the comment. The comment is written in natural language. There are multiple ways of understanding it. It must be written with great care so that people reading it don't misunderstand it. Otherwise it will likely just confuse people. How about putting that effort in writing the code line with clarity? The reader must read and understand it in any case.
This is not black and white. Code comments have their place of course. For example, in sic. situations where one really needs to explain _why_ a certain approach was taken. But usually the why explanation is not needed.
Also, code doesn't have to tell you _everything_. It doesn't have to tell you "what is not there".
Maybe we can both learn here if you elaborated what you think code cannot tell, yet it should?
No, the reader must not need to read the function to understand how it works.
The idea would be that the function names are so good that one does not need to read the function contents, right?
But some things are complicated and may not be expressible with the function name alone.
That's why people write comments. To help readers understand the code.
Let's say I am implementing some algorithm. I may mention the performance characteristics in the comment. Or I may let the readers dig into the code to find out what they are. Seriously, please don't follow "no comments" rule dogmatically.
If I have a function and I need to understand _how_it works_, that is, how does it implement some algorithm, of course I have to read every single line of code to understand how it works!
If the function is named "quicksort", for example, and I suspect it has a bug, I really have to read it to understand whether it implements the quicksort algorithm correctly.
I don't think starting a comment off with "No" is an effective tactic to convey your point or change someone else' mind.
It seems clear to me, as an impartial third party, that there are merits and drawbacks to both of your school's of thought on comments. "No" attempts to shutdown the discussion and makes it hard to discuss these.
This is an odd one for me, 90% of the time I wind up subconsciously ignoring comments that exist in code. It's almost as if I can't see them on the screen. I've been in at least one argument with a coworker where I realized I was ignoring the existence of the comment he was referencing a line above the code we were looking at. On the other side of that, I'm usually adding comments about what's going on all over the place. At least partly to codify what the heck I'm thinking at the time I'm writing it.
To distill that down, document a lot but don't rely on comments you find to be correct.
I read code the way you would a book, constructing this model in my head. Comments to me are a big flashing warning sign saying "this is so important, we added extra comments".
If the comments aren't really that important it will start hurting my ability to read and understand the code quickly.
likewise, if you a comment I wrote, you better sit up and read because it's there for a very good reason.
I'm of the opinion that at the end of the day people need to be able to read code, not use comments as a crutch. There are times when non-obvious things should be documented so developer B doesn't go down the same rabbithole you did, but in general the code should speak for itself.
document gives the context, the code gives the details. If you have both, there should be no real issues with understanding what's going on.
I agree that accurately reading code is important, but no amount of reading just code tell you why something was done.
For a contrived example, why does a specific function/class use an array instead of a dictionary/hash table? A comment explaining that the dictionary was 500x slower in tests could fix that.
I suspect that is exactly the kind of comments you would want someone to "sit up and read" but I didn't want to assume.
Yeah, exactly. If I'm putting comments inside a method (as opposed to the docstring kind of stuff) I'm writing something like "it might seem like it would be better to do [xyz], but that's actually not a good idea because of [abc]."
That's specifically why I said documentation gives the context. Why the API uses a hash table instead of an array is something for the documentation of said API, not code comments.
From my experience there is a correlation between the amount of code comments and defects in the code. The more I see comments in the code base of a module, the more likely it doesn't have any (unit) tests and the more it has defects.
Yet this may just indicate that the code is complex and therefore required comments and contains bugs.
In any case, high comment density is a code smell.
LOL. Comments are not a part of the code. Good comments adds to readability, bad commenting style (e.g. enterprise style comments for everything) affects readability. Comments cannot add bugs to code.
I agree. I was talking about the _amount_ of comments.
Extreme example:
void foobar()
{
// iterate over the list
foreach(var item in list)
{
// send it
sender.send(item);
}
}
I've seen a lot of comments like this. They don't add value. They distract. They must be removed.
They also tell that the author didn't have a clear understanding why code comments should be written, so we may not trust his/her judgement in other programming decisions. The code is suspect. It's a code smell.
It's looks like top-to-bottom style of development: first, algorithm is written in text, then implemented in code. Kind of literate programming. Sometimes it helps, sometimes it not. Usually, this style is used right after the school, by inexperienced programmers incapable to keep algorithm in the head in parallel to development, or when experienced developer does his first steps in a new language.
Most of our very large and complex code base lack comments.
But just yesterday I came across a particularly good comment in an else block, that summarized the story of "how could we have gotten here", and it involved far-flung failures and not so obvious interactions. Very informative to have that right there.
I'd rather have uncommented code that is clear and easy to follow than commented code which is not.
Alas, what I actually get is wrongly commented code that is not easy to follow.
I find it interesting to come across another discussion about writing good code with no real examples of where code has been improved through the use of the practices being advocated.
How am I supposed to know if the comments have really helped the code, or if is that the code was just not written in a self-documenting way to begin with? Or, form the other perspective, how am I to know if the self-documenting code isn't as self-documenting as the original author likes to think? Perhaps even more importantly, how will I learn to take on that better style without examples to study?
In a world where we have a treasure-trove of great open source software, you would think the first step would be to point to exemplar examples to show exactly what can be gained by writing code in the prescribed manner. The "I do it this way and it is great. Believe me.", unfortunately, does not make for a good discussion.
In my experience the worst code that I have seen was the one with the most comments.
If your code is self-explaining, if you have a full test coverage that documents what the code does and how it should be used then the comments are completely useless unless you are publishing a library or an external API.
In my current job I am required to add this completely useless Java Doc / xml doc comments for an application on which only I am working on, that is far more clear than the rest of the codebase, with extensive test coverage and currently I have the same amount of LOC and comments.
It's a total and utter waste of my time and it decreases the productivity so much trying to read the code in the middle of the comments that I had to find a visual studio and Idea extension to hide the comments to avoid getting distracted by all that awful noise.
Needless to say that I completely disagree with the author of the article and I hope that people sooner rather than later will understand that the living documentation of the code is in the code itself and in the tests that, by definition, can't ever be out of sync like the comments.
In particular, it is nice if you bother to document assumptions/constraints related to the expected input and output of your code; why should I have to trace the whole thing to figure that out?
While I do agree with this since thoroughly reading the code itself tells you the how I find comments that tell me what it does to be just as helpful as telling why it does it.
I used to fall into the self-documenting code camp back when I programmed in Objective-C and long descriptive names with named parameters made it read like English but as I've read more code in more languages I actually prefer shorter names supported with code comments that tell me clearly in English what the code does.
For instance earlier today I was reading some of the source code in fossil-scm in the check-in.c file. In it there was a function that was simply named `locate_unmanaged_files`. If there wasn't a detailed comment preceding that function I would have assumed it merely found the files and reported on them directly but after reading the comment explaining what it did I realized it stores the files in a temporary SQLite table, after reading that I learned that "locate" had a wider meaning then to just find it and return it but it rather meant that it is now located for any part of the system to find in the database. It would have taken careful reading of the code to have realized this and it helped me to better focus and understand the code I was reading.
One thing not mentioned is that in an earlier era, code absolutely could not self-document at all. For instance, assembly language in the 80s. Many systems just did not allow for practical longer descriptive names.
Or the traditional C style with extremely long functions that do many things, cryptic names, hardware-related constants or magic numbers, little to no facility for modularization or composability etc.
In that era it was an absolute truism that comments were important. In today's era, comments are usually a symptom.
As someone who had never heard the "self-documenting code" term, I imagined a machine-learning-assisted 'autocomplete' of sorts for code comments or a genius.com for code.
99 comments
[ 2.8 ms ] story [ 210 ms ] threadIf updating the code block results in code with a different intent... you're not updating it, you're replacing it, and should take out the original comment with the original code.
If I have a code block to maintain data synchronization with a a server - that's the intent; if the code is updated from long-polling to websockets, the intent hasn't changed.
I know what you said, and I disagreed; responding back by repeating your disagreement doesn't add any value to the conversation.
Clearly written code already expresses what it does unambiguously. If your code doesn't do what it is supposed to do that is a bigger problem.
I disagree. The _what_ is what your comments should tell me. The contract, and its preconditions and postconditions. Nothing more, nothing less.
If we are speaking of API documentation (i.e. function or module documentation): The "why" can't be explained here. It's at the caller side.
There are more rare cases where it's reasonable to document the implementation of a function because there's a particularly tricky section of code -- and documenting the "why" makes more sense to me here.
Otherwise we need to know via the comment (contract) what is the what, so that we can fix the bug (or even know that there is a bug).
It sometimes happens with self-documenting code too, but only when someone refactors enough of the code so that the class or method no longer matches the original name.
but they usually are.
Just because business folks don't know how to value certain developer practices doesn't let you off the hook. Just do what you have to do and if it takes longer because you had to learn how to do it, then it takes longer.
Let the business folks tell you when it's taking too long to deliver features.
A manager looks at a programmer bringing up something like unit testing as "why the fuck is he asking me about this, it's his job? Obviously because he's asking me it's outside of his professional ken, so that means it's going to take absolutely forever." Out loud he'll just say, "Can you just get the feature done?"
Don't ask, just do it. It takes as long as it takes. If they ask, just say it's not done yet.
But for what it's worth, I agree with you in that I'm still on the hook. Either to help educate my manager, or to pick managers who already understand this stuff.
All they care about is that the code works, and that features can be delivered on time.
That second part "delivered on time" includes maintaining the comments along with the code since it makes the code more readable, and eases future changes. If Management doesn't give you time to write maintainable code (which includes keeping comments in sync with the code), then you may as well start looking for a new job because the technical debt is going to pile up and it's going to get harder and harder to meet deadlines.
I find that I have this problem with my own code. Ridiculous, but it happens.
In terms of developer resources, the act of doing updating the comments is cheap, but the act of making sure it gets done (in a systematic way) is comparatively expensive.
You could always use a tool like Danger (http://danger.systems/) to inspect your code and warn you when code has been updated, but comments nearby have not been.
This is what code coverage analysis/metrics try to address.
> You could always use a tool like Danger (http://danger.systems/) to inspect your code and warn you when code has been updated, but comments nearby have not been.
I'd worry about tuning out said warnings after too many false positives. Comments regular enough to not generate too many false positives can generally be turned into real syntax of some description.
For example: python functions shall have a docstring unless trivial. For external api functions on a class, there must be at least one example. etc etc. Plus, this makes working in ipython really nice!
First, other developers know that comments can grow stale, so they're unlikely to treat them as sacrosanct, although I admit to falling into that trap.
More importantly, most of the types of comments that Eric recommends can drift out of sync with the code and still be useful. Why is this code here? What happened previously that is no longer in the code? What tradeoffs have been chosen?
Yes, because they should be, and are, largely ignored. Of course, deleting them is better than ignoring and not having them in the first place is better than deleting.
Code doesn't depend on variable/function names either. Yet you don't argue they fall out of sync, you simply update them. And this should be done for comments, too.
This is not true of comments.
If we could make outdated comments produce compilation errors, we would live in a wonderful world :)
I really hate it when the compiler ignores my comments.
Doxygen supports documenting function parameters, C++ template parameters, return values then Doxygen and Clang can tell if the name listed for some of those things doesn't match the actual code or if a certain kinds of comments are missing. This won't tell you the documentation is wrong, but it would stop you from adding or removing a function parameters while ignoring documentation comments entirely.
If you want to go crazy you can write Clang plugins using LibTooling and run and code you want and analyze the comments any way you choose.
Depends what language you are working in; in some it won't fail until runtime.
> If we could make outdated comments produce compilation errors, we would live in a wonderful world
It is impossible. The whole point of having comments (and also identifiers) is to tie the code to things that are not formally described. If we would formally describe them, they would become the code.
You could, at best, mark identifiers in comments (and what their refer to), and then you could use this to hint at comments that need to be updated (as somebody else mentioned). But it will never be a perfect process, because there will always be a boundary between formal and informal.
Snarkily, how lazy* do you have to be to not even delete comments you make stale?
* And not as in the virtues of programming lazy.
The closer a piece of documentation is to the code the more likely it is to be updated. External manuals always become stale and comments in C headers are more likely to be stale than comments next to the implementation in C source files (or in any language that doesn't even have that distinction). Comments directly next to complex formulae or other technical BS are most likely to be correct.
Some learn that then suggest getting rid of all comments or putting comments throughout all the code, but if we look at it another can can infer that some of it is code structure problems. A 2k line class with 200+ line methods with comments at the beginning of each method is more likely to have stale comments that any number of tiny classes with 10 line methods. Then comments on a 10 line method are more likely to be read too, because they need to describe less. Ideally they just add the "why" to the "what" the method's name provides. If the whole method and all the comments fit on the same screen then the dev ignoring it must be truly lazy.
All of that being said, I'm not dogmatic about any of the above. I'd prefer my code to be self-documenting, but I understand it isn't always for any number of reasons.
I'm witnessing this currently with the code base I'm maintaining.
To me, those are the functions of commit messages, not code comments.
Of course, a "proper" IDE (and I don't know of any) would give you the context of the commit messages "impinging upon" any given line/block. Maybe something like Light Table (whatever happened to that?) could be configured to do this.
> Presenting an example usage of the function and example output
And that's what (formalized) docs are for. You can certainly generate those from docstring-style comments, if you like, but personally I feel like they get it the way of editing the code itself, and would be better kept in separate files.
(Consider: would you put the gettext translation table for a string, inline inside the source file that contains said string? The arguments are the same, I think.)
For the emacs users: vc-region-history is the best part of emacs 25. I totally consider it nice enough to motivate people to compile 25 by yourself if your distro doesn't provide it yet.
Really, rather than what I said above, it might be better if ever line of code were just always put in context of the PR+code review that allowed it to enter the codebase. Instead of git-blame(1), github-blame(1).
Yeah, it's definitely much more helpful to have it buried below hundreds of merge commit messages.
Indeed not everything can be expressed in methods and variable names etc and so comments can be helpful occasionally. But the focus must be on clearly written code with comments as an exception, not a rule.
As for SDC being myopic, I beg to differ. Code (and contents) is for developers and machines. End users and API consumers should have documents (hence documentation) available to them for purposes of tutorials, user guides and references.
Aside from "why", or explaining overly clever one-liners, the kind of comments I always find necessary are those providing before/after example of data during a transformation; and example strings w/ resulting capture groups for regular expressions.
Example: # "tag1,tag2,tag3:val" => tags: [tag1, tag2], metadata: [tag3:val] # fun one-liner goes here
Yes, you want test cases, and that's where you also put all the weird edge case conditionals; but, it's not like you're going to copy the actual line(s) of code into the test case, so you'd either need to temporarily copy the code (or the data samples) to be adjacent, or open side-by-side editor panes, or what have... All of this is more complicated than an example.
But what about sample data that doesn't fit on one line? Then either your sample data is too complex, or this method is unsuited to your situation.
There are guidelines for maximally legible code. There are no rules. If you follow rules, someday, you will encounter a situation where the rules force you to produce sub-optimal work. "Simply" strive to write legible code, and you will succeed. Strive to follow rules, and you will succeed at following the rules; and maybe you'll succeed at writing legible code.
If a line of code has a comment attached to it, the reader needs to understand both the code and the comment. The comment is written in natural language. There are multiple ways of understanding it. It must be written with great care so that people reading it don't misunderstand it. Otherwise it will likely just confuse people. How about putting that effort in writing the code line with clarity? The reader must read and understand it in any case.
Stick with the code, people!
Also, code doesn't have to tell you _everything_. It doesn't have to tell you "what is not there".
Maybe we can both learn here if you elaborated what you think code cannot tell, yet it should?
The idea would be that the function names are so good that one does not need to read the function contents, right?
But some things are complicated and may not be expressible with the function name alone.
That's why people write comments. To help readers understand the code.
Let's say I am implementing some algorithm. I may mention the performance characteristics in the comment. Or I may let the readers dig into the code to find out what they are. Seriously, please don't follow "no comments" rule dogmatically.
If I have a function and I need to understand _how_it works_, that is, how does it implement some algorithm, of course I have to read every single line of code to understand how it works!
If the function is named "quicksort", for example, and I suspect it has a bug, I really have to read it to understand whether it implements the quicksort algorithm correctly.
It seems clear to me, as an impartial third party, that there are merits and drawbacks to both of your school's of thought on comments. "No" attempts to shutdown the discussion and makes it hard to discuss these.
Because in the cases wherein the code is abstract or dense, a little 'English' can go a long way.
Especially when making use of APIs that are weird and have weird behaviours.
AKA: "I'm breaking xyz convention here because API abc has the following odd, undocumented behaviour (i.e. returns nulls when it should not)"
Comments are not always good, but if there is any reasonable thoughtfulness to them, they will be 'mostly good'.
To distill that down, document a lot but don't rely on comments you find to be correct.
If the comments aren't really that important it will start hurting my ability to read and understand the code quickly.
likewise, if you a comment I wrote, you better sit up and read because it's there for a very good reason.
I'm of the opinion that at the end of the day people need to be able to read code, not use comments as a crutch. There are times when non-obvious things should be documented so developer B doesn't go down the same rabbithole you did, but in general the code should speak for itself.
document gives the context, the code gives the details. If you have both, there should be no real issues with understanding what's going on.
For a contrived example, why does a specific function/class use an array instead of a dictionary/hash table? A comment explaining that the dictionary was 500x slower in tests could fix that.
I suspect that is exactly the kind of comments you would want someone to "sit up and read" but I didn't want to assume.
That's ok - because they are there for reference purposes.
So you can ignore them most of the time.
When there's an issue, or you are reading unfamiliar code - you can reference them.
I leave notes in the code as to the oddities/undocumented nature of weird API dependencies, and of things that were tried in the past and failed.
So many times I've tried to compile some off-the-shelf thing and failed because I didn't read the release notes.
You just have to read the release notes :)
So when you're perusing an unfamiliar module, read the comments :)
I grasp that they can become stale, but on the whole, decent comments are better than none.
Yet this may just indicate that the code is complex and therefore required comments and contains bugs.
In any case, high comment density is a code smell.
What you think about spaces?
I agree. I was talking about the _amount_ of comments.
Extreme example:
I've seen a lot of comments like this. They don't add value. They distract. They must be removed.They also tell that the author didn't have a clear understanding why code comments should be written, so we may not trust his/her judgement in other programming decisions. The code is suspect. It's a code smell.
Not a problem for me. Usually, I clear them out.
But just yesterday I came across a particularly good comment in an else block, that summarized the story of "how could we have gotten here", and it involved far-flung failures and not so obvious interactions. Very informative to have that right there.
Best of both worlds or something.
How am I supposed to know if the comments have really helped the code, or if is that the code was just not written in a self-documenting way to begin with? Or, form the other perspective, how am I to know if the self-documenting code isn't as self-documenting as the original author likes to think? Perhaps even more importantly, how will I learn to take on that better style without examples to study?
In a world where we have a treasure-trove of great open source software, you would think the first step would be to point to exemplar examples to show exactly what can be gained by writing code in the prescribed manner. The "I do it this way and it is great. Believe me.", unfortunately, does not make for a good discussion.
/says so many people I've worked with.
While I do agree with this since thoroughly reading the code itself tells you the how I find comments that tell me what it does to be just as helpful as telling why it does it.
I used to fall into the self-documenting code camp back when I programmed in Objective-C and long descriptive names with named parameters made it read like English but as I've read more code in more languages I actually prefer shorter names supported with code comments that tell me clearly in English what the code does.
For instance earlier today I was reading some of the source code in fossil-scm in the check-in.c file. In it there was a function that was simply named `locate_unmanaged_files`. If there wasn't a detailed comment preceding that function I would have assumed it merely found the files and reported on them directly but after reading the comment explaining what it did I realized it stores the files in a temporary SQLite table, after reading that I learned that "locate" had a wider meaning then to just find it and return it but it rather meant that it is now located for any part of the system to find in the database. It would have taken careful reading of the code to have realized this and it helped me to better focus and understand the code I was reading.
Or the traditional C style with extremely long functions that do many things, cryptic names, hardware-related constants or magic numbers, little to no facility for modularization or composability etc.
In that era it was an absolute truism that comments were important. In today's era, comments are usually a symptom.