Hacker News new | past | comments | ask | show | jobs | submit login
Reasons to avoid code comments (pauloortins.com)
31 points by javinpaul on July 13, 2013 | hide | past | favorite | 53 comments



I'd say only overly verbose documentation is bad.

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.


I'd say the opposite.

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.


Agree completely. Another good example is these guys https://gocardless.com/docs/

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.


...so you're saying, no one will read the documentation, because they'll all be looking at the documentation?

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...)


> ...so you're saying, no one will read the documentation, because they'll all be looking at the documentation?

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.


If your code comments are breaking any DRY principles, then it's likely it's because they're explaining what your code is doing. I agree that properly named variables and well structured code should be easy to understand if you want to know what it's doing.

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.


Yes, especially design decisions and reasons for stuff, that isn't obvious, like why this is looked up each time, and not cached, or why the data representation choosen is as it is, and not something simpler/faster, etc.

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.


I dislike the last example he gives, even though the reason may be a decent one. Having Doc Comments in Java, for example, is great because Eclipse (and other IDEs) will actually explain to you what a function does when it does code completion and the format for those comments looks exactly like that example.

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).


The example given as reason #5 just goes to highlight the original author's ignorance.

  /**
  * 
  * @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...

http://yui.github.io/yuidoc/

I'm sure that the fulltime javascripters here could post better examples and tooling support..


Good god, you've brought back nightmares about WPF documentation now. Want to know what XXX property means in WPF? Well, the documentation will helpfully tell you that "gets or sets the XXX property of the FULLNAMESPACE class."

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.


The comment merely duplicates information already present in the function signature.

    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.


Worse than that, it can get out of step with the method signature. A lot of tools I've seen will take the doc comment as an authority over the method signature, even if they don't match up.

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.


Not only are you right that these docblock comments can get out of sync with the real parameters, but I would argue that it is almost inevitable that they will. I rarely waste my time reading them any more, but when I do, there's something out-of-date more often than not.

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.


The title of the author, or the title of the CD? Or perhaps it's a track title?


If I encountered anyone actually calling that function and seriously wondering what "title" could refer to, my reaction would be to call an ambulance, because they're clearly in the midst of a stroke.

Comments do not exist to explain basic everyday concepts, nor basic linguistic skills.

You might as well ask "what's a CD?".


You assume "addCD" actually adds a CD to, say, a music library, rather than being a butchery of "addToCD". This might be unlikely in Java, but if this were C89 (where no function has a containing class and where no parameter based overloading is possible), I'd be calling you the ambulance if you weren't seriously wondering whether "CD" refers to what's being added to, or what's being added.


Bad names are bad code, and comments are not an excuse for bad code.

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.


And I don't meant to suggest papering over bad naming conventions with comments. You're preaching to the choir there.

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.


If it's that confusing, rename the parameter.

    public void addCD(String cdTitle, String cdAuthor, int numTracks, int durationInMinutes)


Exactly, why write comments if you can choose better names ?


With all the respect in the world, but documentation like that, don't provide any useful information. It only produces noise.


Comments are often a code smell. You should always be thinking "how are people going to figure out how to use or update this code effectively?" And when the response is to add a comment you should first pause and then consider alternatives such as: renaming variables/methods or extracting code/conditions into well-named methods. After you've expended the effort to make the code easier to understand and more "self-documenting" then go back for another pass and ask yourself the same questions, and write comments appropriately.

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).


Pardon the virulence, but this is idiotic advice. Or at the very least, an idiotic generalization.

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.


> Comments are not testable/verifiable

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.

[1] http://docs.python.org/2/library/doctest.html


It works only in python, I think. At time, where is the best practice when testing in python ? Doctests or unittest ?


Good grief. SOME NUMBER blah blah RELIGIOUS ISSUE.

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".


These sort of articles are definitely the worst part of HN. Take some common practice, invent dumb rules against it just to be contrarian, publish and get people fighting against each other.


It isn't to be contrarian. Discuss things like that, make new good practices born. It was the same with goto, singleton pattern and other things.


> @param title

> @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!


In systems grown over many years and by many developers, comments about such things are nearly worthless, because they can't be trusted. I wouldn't be surprised to see a comment saying "title cannot be null" right above code that explicitly permits null. A comment that lists which exceptions can be thrown is highly suspect, I would probably delete that just to avoid confusion, and make sure that it's obvious from the code instead.


When code has been poorly refactored (I'd count "documentation/comments weren't updated") I find knowing the original intent behind classes and methods to be useful in understanding their mutated design, and how it was arrived at.

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?


> comments about such things are nearly worthless

The Java ecosystem lives on such comments. I wouldn't use a Java API without "Javadoc" documentation.


I don't endorse this way of developing software. It's profoundly bad -- in a way that comments can't fix.


Types are typically better documentation than comments:

    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!


You could just write a monad instead.


Those sorts of things are useful, but mainly on API edges. They also tend to get outdated pretty quickly in code with even moderate churn.

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).


When we are writing a comment for a function we are repeating ourselves. We are transgressing the DRY (Don’t Repeat Yourself) principle.

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?


It has to change because our code is not the ends itself, but only a means to an end. The end itself is using rooted in human psychology - 'ease of use', 'problem solving', etc. This means that the end itself cannot ever be truly completed as it's about as close to a random process as you can find. This means that the code itself will have to continue to change to follow the random process it is trying to arrive at.

Simply: the environment the code is executed in changes, and so the code must change.


Here is the exact opposite point of view, that we need massively more comments to the point where they are not merely comments, but comprehensive, prose discussion interwoven with code. As far as arguments to change the status quo go, I think Knuth's has more to recommend it: http://www-cs-faculty.stanford.edu/~uno/lp.html


After looking at the source code for Tex, I have decided literate programming is a massive failure.


I think TeX in particular somewhat suffers from being written in a language few people know (a Pascal variant Knuth invented) and to 70s architectural standards (fixed buffers for everything, etc.).

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


Comments that could have been mechanically manufactured from code "@param databaseWithFruit a database, with fruit" are indeed dumb. I omit them.

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.


It could be a hassle to keep comments as up to the date as the code they are meant to accompany, that I totally agree but I would argue with these main 2 reasons on why I prefer to comment as much as possible and update them as often as the code: 1) I am fairly certain that the next maintainer of my code would appreciate a well-written piece of code with proper explanation for especially clever portions or just plainly horrifying practices done for a production bug fix which must go out in minutes and the poor soul responsible for that already forgot about fixing the fix :).

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.


Bad code has few comments. Good code has many comments. The best code has few comments.


Totally agree.


I used to hold the same opinion, that code should be expressive, so we shouldn't need comments. However, I've found this to be false for a number of reasons:

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?


The best comments are surrounded by pertinent code. I don't think I've seen a workflow yet that allows you to attach specific portions of commit messages to specific code passages, so it's a little difficult to ensure that what you're saying is clear.

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.


> 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.,


API docs are not comments. If Java needs them, they should be maintained and up-to-date. Some languages don't need them to such a degree (type signatures in Haskell are damn expressive).

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.


This is nonsense. I can't count how many times I've come back to some code and had to read a comment to understand why a decision was made or looked over another's work and found a comment to explain it all. The idea that code should be so awesomely pure that it explains itself is laughable in my experience.


In fairness, a good article with actionable, specific observations (and the inline with my vague recollection of recent consensus). Still, posts with titles like this make me think:

- 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.


Lets see.

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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: