Reasons to avoid code comments
pauloortins.com
pauloortins.com
If a situation exists in which someone will access your code without the source code right in front of them; ie. it's a library that will be and depended upon by others, consider:
1) They probably will not compile or read your source code, so no matter how elegant your code is, they'll only see the exposed API, and no how your function works wont be obvious.
2) Automatically generated documentation is usually very poor for unannotated code.
3) Writing simple intuitive APIs is actually very difficult, and the chances that you'll get it right every time are virtually zero.
Maybe internal functions can be 'self documenting', but it's a silly to say documentation, in general, is bad.
Public APIs require documentation; if you don't document it, and the person who has to use it has to hunt down a copy of the source code to find out how to use it, trust me, they will curse you for it, not thank you for writing simple elegant code.
Nobody will read your documentation.
They will be able to see the API, so make sure that it's well designed, and as easy to use as possible (much easier in languages/IDEs with autocompletion).
And they will use code snippets, so make sure that you make those available. Feel free to walk people through the process of using those snippets, so they can understand them, but 99% of devs are just looking for some code they can splat in and get their system working.
A great example of this is the Quick Setup guide for Persona:
https://developer.mozilla.org/en-US/docs/Mozilla/Persona/Qui...
Which walks you through what you need to do, giving you code that you can use at every step.
If I'm looking at an external service/API for use in one of our products the first thing I look for from a technical perspective (is this priced right) is good code samples of API usage, then I look take a look a whistlestop tour through the docs (mostly to get an idea of quality and completeness).
At that point I might whip up a simple project against their API (if they make it easy to do and without having to pay...) and if I like it then I'll buy, Another good example I ran into recently was Nexmo, very easy to use and good docs.
You've lost me I'm afraid.
(unless you're saying that api documentation, specifically, isn't very useful compared to say, examples, in which case, you're agreeing with me, because useless api documentation is what you get when you run a documentation tool over a code base without annotations...)
I think he means that devs won't be reading documentation like a book, chapter by chapter, trying to comprehend what API does, but instead they will look at tutorials and code snippets, and enter your documentation at random points via Google / StackOverflow links, mostly in cases when something is not working.
The purpose of comments are to say why your code is doing what it's doing. These sorts of "why" comments should be encouraged, not avoided.
But there are ways to move some things from comments - gotchas can be made unit tests instead of //WARNING!!! in comments - made a test that checks the implementation for the error that shows when you cache this thing that can't be cached - even if somebody miss the warning in comments he will surely notice the problem when the test fail (comment should still be there so people that read code before making changes won't have to wait AFTER they changed stuff and run unit tests to see they shouldn't do this).
One great practice is to make unit test for every easy-to-reproduct bug, check before you fix the bug that it fails, fix the bug, and commit both test and the fix in one commit.
Some comments can be also moved to commit messages instead - especially comments that explain why something was changed - you can always blame code and see relevant commit messages, and if the code changes blame won't show commit messages for the lines that aren't there. Comments may be still there after a change that made them misleading.
Overall, there are some very good points expressed in the article. I feel like the fact that new programmers are taught to comment a lot is good (completely uncommented code is often horrid, and let's be honest, new programmers often won't write good code). Perhaps there should be a stage later on (and maybe there is) where programmers with more experience are taught that they should actually avoid comments in general and just write good code (with the exception of doc comments, as I mentioned above).
/**
*
* @param title The title of the CD
* @param author The author of the CD
* @param tracks The number of tracks on the CD
* @param durationInMinutes The duration of the CD in minutes
*/
Is a format used for tooling support, it's NOT "just a style".Java & C# both provide format for XML comments, which are then used to generate API documentation and to improve auto-complete.
With these comments, a user of the function doesn't need to read through the source code to understand what it does.
A quick google shows that these tools exist for Javascript:
http://stackoverflow.com/questions/9263005/javascript-docume...
I'm sure that the fulltime javascripters here could post better examples and tooling support..
public void addCD(String title, String author, int tracks, int durationInMinutes)
It's uninteresting and superfluous. Just like virtually all other Javadoc-style comments I've ever seen.Comments do not exist to explain basic everyday concepts, nor basic linguistic skills.
You might as well ask "what's a CD?".
There's also no reason to believe someone with byzantine naming practices is going to be any better at documentation anyway.
And why would a function for adding to a CD have an integer parameter named "tracks"? (If your next argument is "maybe it's for the track number"... Bad name! Bad code!)
Finally, context is important, and considering a single function in isolation and thinking up all the ways in which it might be ambiguous (though I've yet to see anyone identify a plausible way in which this one could possibly be) is ridiculous. In all likelihood, the behavior of a function is even more obvious in the overall context of the system/API it's part of.
What I do mean to suggest is that while in any half decent codebase, addCD should be unambiguous, someone thinking title is ambiguous isn't having a stroke -- at worst they're being incredibly jaded. API design is nontrivial, people make mistakes in the trivial cases distressingly often (due to laziness, lack of familiarity, wildly different backgrounds, or any number of other reasons), and relying on context too much has it's own problems anyways.
For example: We're missing it in the very snippet we're discussing. There's no class shown. You're filling in the blanks with reasonable code. I've seen far too much unreasonable code to dismiss it when talking coding styles, and even reasonable code is only a botched refactoring or two away from being unreasonable.
public void addCD(String cdTitle, String cdAuthor, int numTracks, int durationInMinutes)Javadoc-style for documenting method behaviour is quite often very useful for explaining the edge cases and stuff like that. I wish I could just document the parameters that are interesting, and have the tools merge that with the method signature.
I like your idea of documenting only the interesting aspects of the parameter list. I'd advocate just going ahead with it, using plain old concise English prose to do so. Comments are supposed to be for humans to read anyway.
I've learned that sometimes BIGCORP makes developers document something when they have nothing interesting to say.
Someone should design a programming language without commenting capabilities and figure out a new/different/better way to deal with library API documentation problems as well as implementation documentation.
Generally the only comments you'll have left are API level info and documentation of "intent". Explain the inputs and outputs and their formats of every public method (especially for library code) unless it's mindbogglingly obvious through naming.
One of the most important other questions you should ask yourself when looking at code is how easy it would be for the comments to disagree with the code itself. That's another code smell, you should minimize the opportunities for that and make it as easy as possible to keep things in sync, keep the verbosity at an appropriate level. When I look at examples of my own code that I think are well documented I see some examples with hardly any comments and some where the comments are much longer than the method bodies. Just like everything else, documentation and commenting are judgment calls, don't just try to conform to a rule, use your knowledge and experience and keep reviewing your code for readability (and code you review for others as well, of course).
Sure, comments that tell what a single line of code do are not very useful. They are verbose.
But you definetely should comment on your architecture. What is the role of this class? How does it interact with other classes? Paint me a small picture that helps me quickly grok your software.
Functions/methods also, should be commented: are there inputs that are invalid? Should a particular relation between the inputs be respected? To understand a piece of code, I do not want to read every other piece of code it calls into. A few English sentences are definitely much help. If you use an IDE and a statically typed language, you can even display that by hovering over the function name.
Developers don't need this kind of encouragement. I have never been bothered by excess comments when reading code (at worst a few inaccuracies have crept in), but I almost always wish for more comments and documentation in general.
Although not strictly comments (rather, docstrings, which have a similar purpose), Python's doctest[1] allows you to write code in your docstrings and then test them for correctness.
So I have trouble with any article that starts with SOME NUMBER because that's about as lazy as starting with a definition. It's bad discourse.
And I don't understand how RELIGIOUS ISSUE belongs on HN. In this case it's comments, but it could as easily have been favorite language, editor, or any general dogma.
Those are my "2 reasons to avoid the contentious but vapid article".
> @param author
> @param tracks
> @param durationInMinutes
May the params be null (title, author) or <= 0 (tracks, durationInMinutes)? What happens in such cases? Is an Exception thrown? Which? What exactly is the result of addCD()? Which related methods are available? ...
Yep, avoid bad comments, provide informative comments!
The Java ecosystem lives on such comments. I wouldn't use a Java API without "Javadoc" documentation.
Further, handling of the edge cases may have changed, but many of those changes may be bugs in the code to be fixed rather than intentional design changes to be re-documented. When fishing for the cause of a crash, said comment can help verify the existence of a bug, even if it's not the bug you're looking into.
They can also guide the fixing of that bug. This variable shouldn't be null: is that the fault of the callee for not providing a fallback? the caller for violating function preconditions? caller of caller for the same? another class that had it's invariants violated without asserting?
It would be interesting to be able to link assertions in a method doc with a test, so that the doc export process/IDE will complain if the test ever gets removed (because the API changed).
addCD :: CDCollection -> String -> Maybe String -> NonNegativeInt -> NonNegativeDouble -> Either FailureType CDCollection
This answers all your questions except for "Which related methods are available?" and the anwsers are checked for correctness at compile time!Agreed, but this only applies when code is meant to change. It has been pointed out (perhaps by Knuth on Literate Programming) that a good way of explaining something to another person is to do it in two different ways (comment and code), which is practical when code does not change.
The follow-up question is why does our code have to change so much. We use toolboxes (IDEs, compilers, version control) optimised for change management. Would it be possible to treat our code like the Clojure/Datomic crowd treat immutable data structures?
Simply: the environment the code is executed in changes, and so the code must change.
Better recent examples:
https://news.ycombinator.com/item?id=5998580
http://www.haskell.org/haskellwiki/Haskore
and just about anything in http://coffeescript.org/#literate
That said, people who modify code without seeing if the adjacent comments still make sense are bad. If something is wrong on your screen, you should notice it and fix it.
2) Someone may remember every lines of code that they wrote in the past 3 months or so but I would not. I tend to forget code rather quickly so my comments serve as a memento to my future self, meaning I would do well to keep my comments up to date.
1) Proper comments allow you to explain the reasoning behind the code, not just what the code does.
Excellent examples of this sort of commenting include ZFS's code[1] and Linux's SLAB memory manager[2].
This is important because a lot of the time, there are minutae that are extremely important to get right, but it's not immediately obvious why you did it that way. For instance, maybe there is a special reason fine-grained locking was implemented a certain way, perhaps there is a reason this method of IPC was chosen, etc. A lot of thought goes into properly architectured code, and without comments, future contributors have no idea why this works.
System architecture details become particularly important when you delve into more difficult problems. For instance, I've seen the following snippet of VHDL code:
process(clock)
if(rising_edge(clock)) then
delayed_signal <= signal;
end if
end process
This piece of code delays the signal by one clock cycle, but a lot of time in poorly documented code, there's no explanation why! Maybe there's another signal that needed to be synchronized with this one, so you need another clock cycle. Maybe this signal needed to be re-synchronized into the clock domain and one DFF does the trick. Without appropriate commenting, you'll never know the true purpose of this code, so if you change something around it, there's a higher likelihood that everything will break.2) Proper comments also explain what isn't there: the things that have failed, and why you probably shouldn't try them again.
The OP mentions that sometimes you spend a lot of time optimizing a block of code, only to find out that it doesn't come out better in the long run. Why isn't it commented? By commenting "oh, we tried this other topology, it didn't end up being right for this scenario because of reasons x, y, and z", you can save a lot of grief for somebody down the road.
You might say that the source history should show this, but how often do you look at previous commits when coding? I find that most people ignore the tree until it's time to merge, and even if previous attempts are documented, their reason for removal is often abbreviated in the commit message: "wasn't fast enough"/"didn't work as expected".
You can see the result of this on a large scale, if you take a look at the file-drawer effect[3]. If you dump a huge amount of time/money into projects, and then don't let other people know what happened because it didn't turn out well, people are likely to repeat the same mistakes you made.
3) Proper comments make it easier.
I'll admit it: I'm lazy. If I don't write the comments that specify points 1/2 immediately, as I'm refactoring the code, I'll lose my train of thought. Even if I manage to get away and dump the ideas in another file, they probably won't be as clear as if I wrote it right then and there, with the source code to reinforce my arguments.
The time to context-switch between writing code and writing documentation should be as small as possible, so I'm a big fan of systems like Haddock[4] which allow you to write code and documentation and parse-out the docs into HTML for later browsing.
Ultimately, the code and your comments serve as knowledge for the future, so don't let your time go to waste: document what you did, why you did it, and why maybe other things didn't didn't work.
[1] https://github.com/illumos/illumos-gate/blob/master/usr/src/...
[2] http://lxr.free-electrons.com/source/mm/slab.c
[3] http://skepdic.com/filedrawer.html
[4] http://www.haskell.org/haddock/
Example of great Haddock docs: http://hackage.haskell.org/packages/archive/snap/0.12.0/doc/...
edit: formatting
even if previous attempts are documented, their reason for removal is often abbreviated in the commit message: "wasn't fast enough"/"didn't work as expected".
If we're instructing people to write useful comments, why can't we equally instruct people to write useful commit messages?It's also not guaranteed to stay with the lifetime of the file. This is often a problem if you're downstream; if you just download the source code, it's a lot of steps to go back and get to the source repo and look at all the commit messages.
Additionally, the commit log will be only be a log of deltas, and doesn't give you a picture of what's finally there. With well-written comments, you should get a good idea since they're kept up to date (I hope!) and present a unified picture of what's going on.
Actually deltas are very useful. Blameing code is often very helpful, even if commit messages aren't that great, because you can see which lines were there from the start, and which lines changed together. That alone is often enough to deduce if something you see in code is stupid error, or sth that was intended.
In my company every commit has JIRA task number attached, so for EVERY line of source you can easily find why it's there from the big perspective. That's very valuable, and it's much easier to maintain commit messages than to update comments.
Of course some comments are still needed.,
Higher level comments (“comments” is a suitable word here, it's not something your attach just for the sake of it) is a must for a code that does anything remotely complicated/interesting.
- As a rule of thumb, rules of thumb are useful in many common situations.
- As another rule of thumb, titles which are stated in fairly absolute terms generate more interest.
I think most people agrees on the bad of over-commenting or wrong-commenting.
But I would like to review your reasons:
"1. They tend to encourage bad code."
I don't think so. I've seen great comments, even if it's not a cool topic.
There is some factors which may change the quality of a comment, a lot of them are cosmetics, but there are other like: the capacity of the programer to empathise with future maintainers/users and think on them, the capacity of the programer to redact good comments and think interesting messages to people following the code, the committing level of the programer with the future of the project, etc...
But I don't see how comments encourage bad code. People can make bad code, and bad comments, and good code, and good comments.
"2. We spend more time writing and maintaining them."
If a comment is making you loose time, it's a wrong comment. All you use programming is to save time.
The reasons you give there, point more to poor designs or inconsistent project managements.
"3. Comments are not testable/verifiable."
All is testable, hint: search in metacpan for: test pod
You can introduce deprecation policies, in your code, in your tests and... in your comments. Check for validity, spell, dead-links, text matchings, etc... I don't know why you assert you cannot.
"4. They are less reliable than the documented code"
That points to wrong comments.
If a comment is wrong, is wrong, the same as if a line of code is wrong, it, is, wrong.
If a comment is in the code, should be because it helps to the usage (typically the maintenance) of the code.
In the case of libraries (typical usage of the code: reuse), it's usual nowadays that what you find in comments, is the metadata needed to build the library documentation.
I think both cases of comments, internal maintenance and public "face" of the code, imho should be always as reliable as the code lines if we want to treat seriously a project. I know it's not, but that's just lazy/ego/copy people.
"5. Some comment styles can fill a lot of screen space"
That's not a reason to not use them. If they fill screen space with _useful_ information.
Your programming oriented text editors, eventually can (un)collapse comments.
So, that is my review to your reasons.
I could have write:
0. On bash, long comments slow down execution (measurable at big scale).
1. Wen I code for myself, I don't comment.
2. As we now there is not going to be time to document this project, we just "do it".
That are valid reasons for me.
Best regards.