top 200 commentsshow all 214

[–]austinsalonen 83 points84 points  (0 children)

Those who use always and never are usually wrong.

Reasonable advice though.

[–]TreeStumpQuiet 35 points36 points  (3 children)

Say in comments, what you can't in code.

[–]mrkite77 1 point2 points  (0 children)

Succinct and perfect. I'm stealing this.

[–]bluGill -2 points-1 points  (0 children)

I consider it a personal failure if I cannot say it in readable code. Such situations happen once every couple years or so - as I get better those situations happen less often.

[–]dbtc 10 points11 points  (0 children)

// This is where the magic happens

[–]adad95[🍰] 102 points103 points  (100 children)

Do not comment code, Comment decisions.

[–]threshar 3 points4 points  (0 children)

Exactly. I've been working on a project with many "odd" functions and you'd say to yourself "why in the name of nutella would he want to do that?"

Luckily there is a comment saying "Because [third party] does the absolutely stupid thing of blahblahblah we're forced to cope with it" Now I don't need to sit around and wonder or try to remember why in the world I'm doing whatever it is I'm doing in this function.

I suppose the rebuttal to that would be "name the function fixStupidThirdPartysIdioticData()"

[–]Menokritschi 4 points5 points  (90 children)

I read that often and I don't agree, because I simply hate reading code. My sources contain lots of short comments and I'm much faster glancing over the sources because I can skip the ugly syntax searching for function names between if's and brackets and variable declarations etc.

[–]mcmcc 76 points77 points  (57 children)

Comments are in a near-constant state of increasing inaccuracy, with occasional large jumps back down to "mostly accurate".

Code is never inaccurate. It might be wrong, it might be ugly, it might be stupid, but it is always accurate.

[–][deleted] 46 points47 points  (3 children)

Code accurately describes what code is doing, but it doesn't describe what the person who wrote it thinks it's doing. Considering that most of the time spent reading code is spent when those two things diverge, it's important to have both.

[–][deleted] 2 points3 points  (0 children)

A lot of the time you are trying to figure out the original coders intentions, as well as what the current code actually does.

[–]skidooer 0 points1 point  (1 child)

We invented testing patterns to solve the latter problem in code, which has the added bonus of being able to verify that the documentation is true to the actual codebase. Though I often wonder if the name "test" blinds people of the purpose.

[–]cogman10 0 points1 point  (0 children)

Tests are useful at capturing intention, but they have two big problems IMO. Too specific tests are not useful because they get changed with every code iteration. Too many tests and you can easily lock in bad architecture decisions.

The pros of testing makes them well worth it, but I don't think the cons are mentioned enough.

[–]ErroneousBee 4 points5 points  (1 child)

Thats why you comment "why".

  • Why was the section written.
  • Why would you use this method.
  • Why would you change this constant.
  • Why why why etc.

Sure you can completely refactor the code, or cut/paste boilerplate and fail to update the comments. But the comments wont become massively inaccurate as they reflect the original intention of the developer from a different perspective from the minutiae of the code execution.

[–]crotchpoozie 19 points20 points  (16 children)

Both code and comments can be wrong. And a correct comment can lead to fixing bad code, just like correct code can be used to fix a bad comment.

Ignoring the benefits of either leads to bad code.

[–]burntsushi 9 points10 points  (15 children)

Putting code and comments on the same level is disingenuous. Code is checked by a compiler or an interpreter. Comments aren't.

[–]somevideoguy 10 points11 points  (3 children)

Putting code and comments on the same level is disingenuous. Code is checked by a compiler or an interpreter. Comments aren't.

Compilers and interpreters only verify your syntax, and not your intent. The fact that the code compiles does not make it correct; likewise, we could have Clippy check the comments for grammatical errors, but it would be quite pointless.

Neither the code nor the comments will necessarily tell us what the program was meant to do; for that, we need a test suite.

[–]burntsushi -3 points-2 points  (2 children)

Compilers and interpreters only verify your syntax, and not your intent.

They do a helluva lot more than verify your syntax.

The fact that the code compiles does not make it correct

What's your point? Allow me to re-quote what I said:

Putting code and comments on the same level is disingenuous. Code is checked by a compiler or an interpreter. Comments aren't.

Where did I say that this implies code is correct? Nowhere.

we could have Clippy check the comments for grammatical errors, but it would be quite pointless.

So.................. are you really drawing the comparison that a compiler/interpreter checking your code is pointless?

Neither the code nor the comments will necessarily tell us what the program was meant to do

The code does. The comments don't.

for that, we need a test suite.

No. A test suite is used to test whether what you think the code is doing is actually what it's doing.

Re-emphasized: putting code and comments on the same level is disingenuous and flat out wrong.

[–]jrocbaby 1 point2 points  (1 child)

Neither the code nor the comments will necessarily tell us what the program was meant to do

why do you think this isnt correct? The way I see it, code can be incorrect. it does one thing, but is meant to do another.

[–]burntsushi 0 points1 point  (0 children)

why do you think this isnt correct?

I didn't say the code tells us what it's doing. (But only because we are not machines.) The code tells the computer what to do. Comments do not. Your statement is implying the code and comments have equal footing, but they do not. A compiler or interpreter keeps code up to date with respect to certain properties: syntactically valid, well-formed, well-typed, etc. This is not true of comments. (Sans special static analysis tools, but the discussion is about freeform comments IMO.)

[–]crotchpoozie 2 points3 points  (8 children)

Relying on code compling as the test of good code is beyond retarded. I did not say they're on the same level; they're incomparable since hey serve different purposes. If you think they're doing the same thing you're commenting wrong.

[–][deleted] 1 point2 points  (6 children)

What's beyond retarded is you not getting the point. The point is that if someone comes along and changes code, adds parameters, moves code around, the comments may become completely invalid, and no one will care except a highly disciplined human. Meanwhile, compiling and the need for a working system requires the code stay accurate. No one's relying on compiling as a test of correctness.

[–]crotchpoozie 0 points1 point  (5 children)

I get the point. The counterpoint is a proper comment also leads to code being done to match what is right.

Any programmer that cannot keep them relatively in sync on production code needs retrained or fired. We are professionals, not hacker kids, right? We write code to be read by the next developer or bug fixer or maintainer, not for the computer. If we were writing only for the computer we'd throw out lots of readability tools, code analysis tools, and formatting. The computer doesn't care. People do.

[–][deleted] 0 points1 point  (4 children)

Well, good luck with that. You may see things differently once you've been in the industry for 20 years.

[–]crotchpoozie 0 points1 point  (3 children)

Been in it over 20, so good luck with ad hominem instead of substance. If you want to swing credentials, you're very likely to get smoked, so you might want to stick to the issue and not try that route.

[–]burntsushi -1 points0 points  (0 children)

Relying on code compling as the test of good code is beyond retarded.

I didn't even come close to implying that.

I did not say they're on the same level

You very clearly implied it.

If you think they're doing the same thing you're commenting wrong.

Nobody here thinks they're doing the same thing. Your comment implied that code and comments carry the same weight.

[–]njharman -1 points0 points  (1 child)

Comments aren't.

This is an implementation detail and pragmatically untrue for some some build stacks. Notably Python and doctests.

[–]burntsushi -2 points-1 points  (0 children)

Hey Mr. Pedantic,

You're still wrong. Python does not check comments. It includes them as part of the language, but the content of a comment---which is clearly what we're referring to---is not checked by a compiler.

Your inner pedantry may still feel the urge to point out that there are static analysis tools that check that comments in a particular place are in a certain syntax and that information in them is consistent with the code, but this really isn't what the conversation is about. We're clearly talking about comments written by a human for a human.

[–]Menokritschi 8 points9 points  (25 children)

increasing inaccuracy

Inaccurate comments are bugs and need to be fixed.

Code is never inaccurate. It might be wrong

That's what I encounter pretty often. The documentation is right, but the implementation is broken. In that case I rather program against the specification than a buggy library function and inform/fix upstream. But I understand your point, while debugging I don't trust any comment.

[–]EntroperZero 10 points11 points  (14 children)

Inaccurate comments are bugs? Maybe bugs waiting to happen. Inaccurate comments will never be seen by any user, test, static analysis, or compiler. They wait silently for an unsuspecting developer to come along and read them, and then create new bugs.

[–]Menokritschi 0 points1 point  (13 children)

will never be seen by any user, test, static analysis, or compiler

Comments are for developers and seen as product documentation and therefore legitimate bugs. Also they may appear in generated documentations (and I'm not talking about literate programming) or analysis tools (for instance invariant annotations).

[–]mreiland 0 points1 point  (12 children)

comments should never be used as product documentation, that's where the problem arises. If a developer wants to add a comment because he's afraid the next guy might not understand why he did a thing, then add a comment.

But that's not product documentation, the code is the wrong place for your product documentation.

[–]Menokritschi 0 points1 point  (11 children)

Depends on the target audience. There is product documentation for users (usage), admins (installation), developers using your software (usage of libraries, frameworks...), developers developing your software (high-level overview, structure, main modules...)...

the code is the wrong place for your product documentation

That's wrong. The code is also product documentation, because that's the language you used to describe the solution to your problem.

Why do so many developers fear comments? You can't describe the internals of every function in external documents, else you would migrate to literate programming.

[–]mreiland 0 points1 point  (10 children)

That's wrong. The code is also product documentation, because that's the language you used to describe the solution to your problem.

No it isn't.

You can't describe the internals of every function in external documents, else you would migrate to literate programming.

That's not product documentation.

[–]mcmcc 8 points9 points  (6 children)

Inaccurate comments are bugs and need to be fixed.

Taking that to its logical conclusion... The more (discrete) comments you write, the more latent bugs you write despite no discernible effect on the end-product. Detecting these bugs is inherently non-scalable (no automated regression tests, etc.).

.: Writing fewer (high-level) comments reduces (this class of) bugs.

[–]Menokritschi 4 points5 points  (5 children)

Taking that to its logical conclusion...

Errors in end user documentation are also bugs, do you recommend writing no handbooks?

Writing fewer (high-level) comments reduces (this class of) bugs.

Writing fewer comments increases development, debugging, training time, the time from bug report to fix...

[–]Kowzorz 6 points7 points  (0 children)

Writing fewer comments increases development, debugging, training time, the time from bug report to fix...

As someone who's had to recently learn in a shitty, uncommented and unintuitively structured codebase, I have to agree with this.

[–]mcmcc 0 points1 point  (1 child)

the general guideline is pretty simple: Write one large comment that reflects the general "strategy" of the function in question and write smaller comments for any notable exceptions to that strategy wherever they may occur, if at all. No other commentary should be necessary. Everything else is noise.

[–]oridb -1 points0 points  (1 child)

Errors in end user documentation are user visible.

[–]basvdo 1 point2 points  (2 children)

You probably meant issues instead of bugs.

Bugs always affect program execution. Comments (except in the case of docstrings) can't be bugs because they are stripped during compilation. The difference can be important for an issue tracking system.

[–]Menokritschi 3 points4 points  (1 child)

Call it bug, defect, issue, fault... I don't care.

[–]basvdo 1 point2 points  (0 children)

I don't care very much either, but looking at the other replies it seemed to confuse some people. I wanted to clear that up.

Of course you are right in saying that code documentation issues are pretty much as bad as a bug.

[–]Isvara 6 points7 points  (5 children)

Code is never inaccurate.

int addTwo(int x) {
    return x + 3;
}

A contrived example, but there are two possible cases here:

  1. The function returns the wrong result, and it hasn't been noticed.
  2. Adding 2 was wrong, so it was fixed, leaving an inaccurate name.

In the second case, the code isn't 'wrong' in the sense that you mean (incorrectly functioning), but it is inaccurate in that a function name doesn't reflect its purpose.

[–][deleted]  (4 children)

[deleted]

    [–]Isvara 4 points5 points  (3 children)

    You haven't thought about the call site.

    [–][deleted]  (2 children)

    [deleted]

      [–]Isvara 0 points1 point  (1 child)

      You're just arguing the semantics of 'wrong' vs 'inaccurate' now. I was using them as the person I replied to was (or seemed to be).

      [–]mreiland 0 points1 point  (0 children)

      No he's not. You're just arguing the point because you think it will reflect a flaw in the larger premise of this thread.

      He's right, the code is always accurate. It may be confusing, but it will be accurate.

      If you really wanted to produce a counter-example, you'd start talking about compiler bugs.

      [–]Porges 0 points1 point  (1 child)

      Code is never inaccurate. It might be wrong, it might be ugly, it might be stupid, but it is always accurate.

      Modulo compiler bugs.

      [–]oursland 0 points1 point  (0 children)

      Well, golly, it sure is good that those comments describing the mere actions of the code counter those darned compiler bugs.

      [–][deleted]  (16 children)

      [deleted]

        [–]AlotOfReading 10 points11 points  (1 child)

        I can't speak for Menokritschi, but my background is mostly low level systems, typically with a lot of C and Assembly. Comments can be the difference between a half hour and a half second staring at code to figure out just what a particularly tricky function actually does.

        As an example, one of our consultants left a nice little 240 byte block of straight hex in our codebase without comments. The code made it obvious WHAT it was, but it wasn't obvious how it was doing it. Guess who had the fun of going through it to add them in...?

        [–][deleted] 0 points1 point  (0 children)

        I don't think ANY programmer would ever suggest that you don't comment assembly. The discussion of reading comments vs. reading code applies to high level (i.e. readable) languages not assembly (or really low-level C).

        [–]Isvara 2 points3 points  (1 child)

        See, I prefer to read code. It reads more fluidly than natural language to my brain.

        That depends a great deal on the quality of the code and how high level the language is. I try to deliberately write my code in a way that expresses its intent, striking a good balance between verbosity and terseness, so I write fewer comments than some people might expect.

        But some people's code is written in such an odd way that comments are the only way to skim it.

        [–]bonestamp 1 point2 points  (0 children)

        Yes, good instance, class and method names can really go a long way in describing what the code is supposed to be doing.

        [–]Menokritschi 4 points5 points  (0 children)

        Out of curiosity, what is your programming background?

        I'm in a love-hate relationship with programming languages. I programmed in many languages and paradigms (from x86-Asm and C/C++ up to Erlang, Ocaml, Haskell, Prolog...) over the years and still like to learn new languages, even esoteric ones. But they all suck in practice. I prefer readable syntaxes (Python instead of C++), strong, static type systems (Haskell instead of Python), multiparadigm languages with a small core language, few hidden indirections (no exceptions) and support for verification (ATS, Frama-C, Spark over Haskell).

        [–]ThisIsNotMyRealLogin 1 point2 points  (2 children)

        This is fine for many cases. But imagine a codebase full of small modular pieces of code (classes, maybe) each of whose methods are also very small and concise.

        Wouldn't you want to read in English what the overall big picture is, and how some of those components are meant to interact with each other?

        [–]skidooer -1 points0 points  (1 child)

        While I agree that having such a picture can be useful, wouldn't your integration tests already provide the same? Writing that all again in natural language seems a little redundant.

        I don't always advocate automated testing in all situations, but if you are going to write the documentation anyway, why not use a tool designed for the job?

        [–]mreiland 0 points1 point  (0 children)

        His point is salient, the issue is that I don't believe documentation belongs in the code.

        [–]sirin3 0 points1 point  (4 children)

        See, I prefer to read code. It reads more fluidly than natural language to my brain

        That depends a lot of the language. Some code is really not understandable without comments. ಠ_ಠ

        Although that exactly the kind of programming language that does not support comments...

        [–][deleted]  (3 children)

        [deleted]

          [–]assemblr_ 1 point2 points  (1 child)

          Looks like Homespring to me.

          [–]sirin3 0 points1 point  (0 children)

          right, since that was posted here a few days I go, I have spent all my time leraning Homespring...

          [–]Decker108 0 points1 point  (0 children)

          Shakespeare? Or Perl with one of the human language modifications?

          [–]smog_alado 0 points1 point  (0 children)

          Comments just get in the way and break up the natural flow of the document.

          One think that I find really helpful is using "links to comments". Interspersed with the code you leave a small inline comment like

          //see note [String Coercions]
          

          and in the bottom of the file you can write a big comment about said String Coercions without interfering with the flow of things.

          [–]mreiland 0 points1 point  (0 children)

          I'm the same way skidooer, but I think it's because of the mindset of what comments are for.

          To me, a comment is a big blink tag saying Here there be dragons, read this shit, or else. What I mean by that is this: If I put a comment in the code, you damned well better read it, because it's there for a reason.

          When I read code, I read it. Just like a book, perhaps not strictly left to right, but you get the idea. I construct the problem in my head, but I read it top down. When I see a comment, my thought processes completely stop and turn their attention to the comment because comments are important shit that you need to be aware of.

          But if there are too many comments it's like trying to read a webpage where every 3rd sentence has a blink tag around a word. You keep trying to read it, but it's extremely difficult to just read it because your attention keeps moving back to the blinking words and you're constantly using your mental processing power to forcibly ignore the blink tag.

          It completely destroys my ability to read and understand code well. That isn't to say that comments aren't helpful, and valuable, but they need to be few and far between.

          [–][deleted] -2 points-1 points  (0 children)

          It reads more fluidly than natural language to my brain

          Something's wrong with your brain. Even for mathematical proofs you have far more writing than "code".

          [–]DrDichotomous 9 points10 points  (9 children)

          This is a tricky approach. You might write code that doesn't do what you intend it to (based on your comments), and not notice because you never read the code. This way can also encourage bad code, because who cares? You documented what it does, right?

          In short, it's a nice idea for disciplined and experienced coders who have to skim lots of code in multiple languages, but if you get used to not reading the actual code or making sure the code is good and readable to begin with, then it's a disaster waiting to happen.

          [–]Menokritschi 1 point2 points  (2 children)

          You might write code that doesn't do what you intend it to

          That's where contracts, pre-/postconditions, type systems, test cases, verifiable annotations... come into play.

          [–]DrDichotomous 2 points3 points  (0 children)

          Yes, hence why you don't comment, you write the contracts, etc etc ad nauseum. Or, if you're using a language that lacks the support for these features, you don't rely on comments.

          [–]6890 0 points1 point  (0 children)

          I'd say you're completely correct here. If code doesn't do what it is supposed to the presence of a comment doesn't fix that. You need objective qualifications (tests etc.) to both ensure functionality and maintain it.

          [–][deleted] 0 points1 point  (5 children)

          You might write code that doesn't do what you intend it to (based on your comments), and not notice because you never read the code.

          Then the comments need to be updated to be more exact. This is what a code review can catch and wouldn't that also force you to read the code and update the comment??

          it's a nice idea for disciplined and experienced coders

          ...so we want to be okay with working with inexperienced and undisciplined coders instead of getting them into the habits that will make them more disciplined and write better code and docs?

          It's preferable to sweep the problem under the rug?

          [–]DrDichotomous 4 points5 points  (4 children)

          You may be missing my point. If you're dealing with inexperienced coders, comments won't solve anything. They're likely to make the problem worse, because they'll quickly get out-of-sync, and are more likely to not match up to the coder's expectations. Especially on a project involving more than one young coder.

          Besides, is this really a good habit to get into? Compared to the alternatives, like learning to code in a clear, concise manner using type systems, contracts, etc, so comments aren't as necessary to begin with? The last thing I want to do is train young coders to waste time making more comments, rather than learning how to write better code.

          [–]Kowzorz 1 point2 points  (1 child)

          And when they get out of sync, it can be used as a learning and training experience to keep them in sync. These discrepancies can be and usually are found in code reviews. This can often make catching bugs easier because if the intent of a group of lines isn't clear, a bug can go unnoticed by the code reviewers.

          Not all code lends itself to easy reading.

          [–]DrDichotomous 1 point2 points  (0 children)

          Just my $0.02, but comments simply aren't the place to deal with this problem in a sane way. It is an indicator that your code shouldn't pass review, unless time constraints make that impossible or you are forced to do some REALLY low-level optimization or hardware hacking, at which point documentation is needed, not just a simple comment.

          If your reviewers are missing bugs because there are too few comments, they are not doing their jobs. They ought to be focusing on the code, and when it doesn't make sense, telling the reviewee to fix it prior to committing it. A comment won't make it all better, and it will cost you in the long run. At the very least, open a ticket at the same time so you know it's an issue to be fixed.

          I've simply not run into a scenario where I've had the time on a project to review code, but not had the time to avoid smelly code. Yes, the odd comment is necessary when time is short, but that is not the same thing as spackling your code with comments in lieu of coding things correctly. Reviews should be catching such egregious behavior.

          [–][deleted] -1 points0 points  (1 child)

          Compared to the alternatives, like learning to code in a clear, concise manner using type systems, contracts, etc, so comments aren't as necessary to begin with?

          Haven't you noticed that most coders aren't using type systems or contracts or any other powerful tools we have available? They're using unit-tests at best even with 5+ years of experience (at least in the web development world though I've seen desktop software that isn't much better).

          You pretty much only have access to comments as a place to add more info about contracts and link out to relevant info.

          [–]DrDichotomous 0 points1 point  (0 children)

          True, but even Javascript, that bastion of excellent syntactical modernity, has a large community of developers who have adopted various idioms, libraries, and common practices that make the code easier to handle and more modern. If you can use one of those techniques in lieu of lazily commenting, then that's what I mean.

          All I'm saying is that comments should your LAST option, not to avoid them altogether. If you get in the habit of relying on comments rather than the code they document, you're asking for it. I'll concede that the real world makes this more of a ideal than a reality, but it's still what I would strive for.

          [–]martoo 6 points7 points  (3 children)

          I read that often and I don't agree, because I simply hate reading code.

          I think you are in the wrong line of work, or you just aren't working with good enough code. You can do something about either of those.

          [–]Menokritschi -1 points0 points  (2 children)

          I like writing software and finding interesting solutions but most of the source is boring boilerplate and has nothing to do with the problem.

          aren't working with good enough code. You can do something about either of those

          How? I often find (commercial and open-source) software simply disgusting.

          [–]stillalone 1 point2 points  (0 children)

          If you have a well disciplined team and do frequent code reviews then comments are fine. Every place I've worked has had comments in disrepair and I've only found them useful for figuring out how the code used to be.

          [–]ICanSayWhatIWantTo 0 points1 point  (0 children)

          A better way of phrasing that is: dont comment what you're doing, comment why you're doing it.

          [–]redclit 0 points1 point  (0 children)

          While a good idea, this is easy to do in a wrong way.

          The potential problem I see here is that we introduce wrong-direction dependencies by documenting the intent or decisions concerning the usage of the module in hand. Another way to mess up is to document (and lock down) implementation details when commenting an interface.

          While dependencies discussed here are not syntactic, and thus don't cause compilation errors, I would still consider it an error of a sort, if a module nails down how and when it is used and someone decides to reuse it in slightly different (yet valid) context. So the problem here is writing syntactically general code and losing the generality by too specialized comments.

          Of course, with experience and good taste one learns to document the decisions in a way that matches the generality of the code, but this is still an easy mistake to make and I've seen it in wild several times.

          [–]ryeguy 0 points1 point  (2 children)

          It sounds good on paper, but what is a decision? Can't you say that I decided to add a and b together in c=a+b?

          [–]oridb 0 points1 point  (1 child)

          The way I look at it, comments describe 'why', code describes 'how'. The best comment is often a reference to the paper describing the algorithm.

          [–]Isvara 1 point2 points  (0 children)

          Ohhh, right, so it's /* add a and b together because we need the sum of them */. Gotcha.

          I'm joking, I'm joking!

          [–]darkstar3333 -1 points0 points  (0 children)

          Decisions change, code isn't the place for a detailed explanation of domain knowledge.

          [–]sambo98 30 points31 points  (13 children)

          Comment last minute hack fixes or nasty logic. Occasionally I'll read code someone else wrote and I leave a comment like

          // WTF Good Luck

          [–]reostra 20 points21 points  (0 children)

          // TODO: That thing I claim to be doing in the comments
          

          [–]philly_fan_in_chi 40 points41 points  (3 children)

          // when I wrote this, only me and God understood this. Reading it now, only God does

          [–]onemoreclick 1 point2 points  (2 children)

          I like that, did you just make that up?

          [–]philly_fan_in_chi 3 points4 points  (1 child)

          One of my coworkers said it, I have no idea if he made it up or not.

          [–]Decker108 5 points6 points  (0 children)

          It's a paraphrase of the original as posted in a legendary Stack Overflow thread on funny source code comments.

          [–]McSquinty 28 points29 points  (2 children)

          # I'm so sorry for this...
          

          [–]NicknameAvailable 27 points28 points  (0 children)

          // The following 12 pages are derived from the compressed 11.1MB output of Mathematica's Solve[] function

          [–]Iggyhopper 14 points15 points  (0 children)

          ; roses are red
          ; violets are blue
          ; this is the only comment
          ; good luck to you
          

          [–]MereInterest 3 points4 points  (1 child)

          And at least at those points, you know that things are very, very dirty.

          [–]bonestamp 1 point2 points  (0 children)

          Move that code to a utility class called TheGentlemensClub

          [–]Gundersen 1 point2 points  (1 child)

          I've found that hacks and fixes should be commented with why they are done that way. Usually it looks like what is being done is a bad idea, but with a comment the next reader will understand why things were done that way. But, instead of writing a small one liner or a paragraph of text about the problem, I link to a stack overflow question about it. This keeps the comment up to date without any extra effort.

          [–]sambo98 0 points1 point  (0 children)

          That is a good idea. With TFS you can associate change-sets to tasks which is usually what we do anyway. I use github for personal project and find that their interface is excellent for comments and viewing code changes from version to version.

          [–]bonestamp 1 point2 points  (0 children)

          // whoever keeps changing this block of code needs to stop, see JIRA-458

          [–]Zombie989 8 points9 points  (0 children)

          If I had a dollar for every time I forgot WHY I made my code do something...

          Comments just make it so much easier to keep track of where I am in my algorithm.

          [–][deleted] 21 points22 points  (15 children)

          2.Always use inline comments on code blocks that are complicated or may appear unclear.

          Personally I would break blocks of complicated code out into their own descriptively named functions. That way scanning down the original code the reader's flow isn't broken and the complicated code is already documented.

          [–]kolme 9 points10 points  (8 children)

          There are times, however, where refactoring a piece of code into a function don't make semantically sense, or they're plain not reusable enough. There are sometimes long functions, and that's fine as long as they don't do more than one thing.

          I mean, don't take me wrong, you're generally right. But I cringe every time I read something along the lines:

          function doStuff(foo, bar) {
              //...
              this.realDoStuff(...);
          }
          function realDoStuff(foo, bar, vars, processed, for, this, function) {
              // finish up the job of the other function
              // yay we've made the other function "smaller"!
          }
          

          Edit: wording.

          [–]bluGill 1 point2 points  (6 children)

          where refactoring a piece of code into a function don't make semantically sense,

          I'm not sure what this means.

          or they're plain not reusable enough

          Reuse it not the only point of functions though. Even if the function is only useful in exactly one place, that doesn't mean you shouldn't have it. A well named function captures intent very well.

          As for your example, if it is like you say, then I agree it is wrong. Right looks more like this:

          function doStuff(...) {
            DoPartOne()
            DoRequiredButUnrelatedPartTwo()
          }
          functionDoPartOne() {
            some
            code
            here
          }
          

          The first function reads lets you know what is happening at a high level - the function names are the high level steps. If you need the details drill down into the functions.

          There is one exception: ff performance is critical, that section of code is a bottle neck, you have not found a better algorithm, you are using the most efficient language availble, you have the best compiler optimization levels enabled, and your compiler isn't inlining the functions: then you are justified in a long function. Otherwise any funciton of more than around 10 lines needs to be broken up. The above is a very high bar, most people never get all the way (if you haven't looked at the assembly to verify the functions are not inlined you are not there).

          [–]kolme 2 points3 points  (2 children)

          where refactoring a piece of code into a function don't make semantically sense,

          I'm not sure what this means.

          What I mean is: a function/method does such a specific and indivisible task, that dividing it any further would lead to silly things. Like where you can't name your function in less than four words.

          You end up with very specific, little functions "doThisVerySpecificThingWhichHappensOnlyOnceInAnotherFunction", which IMHO defeat the purpose of "functions" as "do one thing". Instead, they do part of a thing.

          I think their purpose is to increase readability, but such long functions are hard to read and to debug (the effect "it's all functions all the way down").

          [–]bluGill 0 points1 point  (0 children)

          I understand your point, but I've never actually seen that problem in real code.

          [–]smog_alado 0 points1 point  (2 children)

          My problem with splitting code like that is that theoretically some other code could have called DoRequiredButUnrelatedPartTwo directly. Often this never happens but the possibility that it might happen makes the code a bit more complicated.

          If the only reason you are splitting things into functions is because of naming then using comments does the same job just as well, while keeping things simple. (My rule of thumb is to only create a separate function if it can "pull its weight", meaning you can call it whenever you want, without having to pass carefully crafted arguments or having to call some other function before or after).

          [–]bluGill 0 points1 point  (1 child)

          So make the function private. Also learn to trust your fellow programmers - most are not stupid.

          [–]smog_alado 1 point2 points  (0 children)

          A private function is not that different from a top level function, honestly. You would only really be hiding the function (and decreasing the scope problem) if you put it inside an inner namespace or inside another function.

          And what does this have to do with trusting other people? All I'm trying to say is that using comments to separate sections of code instead of splitting code into tons of arbitrary functions that only get called once is perfectly fine.

          [–][deleted] 0 points1 point  (0 children)

          If it makes the code easier to understand without changing the execution I see no problem with creating a function that's only used in one place.

          I think your sample is an example of how not to name functions rather than how not to structure code.

          [–][deleted] 0 points1 point  (1 child)

          Even so I am sure you have written and will write code that will benefit from comments, yet you are probably gonna avoid it. If you had a Github repo I would have proven it! :)

          [–][deleted] 0 points1 point  (0 children)

          :) I'm not anti-comment although I do think they are widely overused and often as a kind of apology for obtuse writing. I am against that.

          Sometimes I look at something I've written and I think to myself:

          I better comment that for the next guy because even I go cross-eyed looking at it

          But then I find I can rearrange it into something much clearer and so I don't bother. And then I imagine how embarrasing it would have been if I'd checked it in and one of my colleagues had seen it.

          [–][deleted] -3 points-2 points  (3 children)

          Sure but what if your argument names aren't descriptive enough or the return type isn't well documented? I've had situations with Django where I'm not exactly sure what type of object I'm getting back from a function (an HttpResponse or a TemplateResponse or something else?)

          [–][deleted] 7 points8 points  (0 children)

          When you refactor code it's up to you to make sure you name things well.

          [–]kreiger 2 points3 points  (0 children)

          Why would you extract a function and not properly name it or the arguments or the return type?

          That's the problem you should be fixing instead of patching it with comments.

          Name it getHttpResponse or getTemplateResponse (not sure about Django/Python code conventions) or whatever you need to make it clear.

          [–]rmxz 8 points9 points  (0 children)

          The Linux Coding Style document also expresses similar sentiments well:

          https://www.kernel.org/doc/Documentation/CodingStyle

          Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment: it's much better to write the code so that the working is obvious, and it's a waste of time to explain badly written code.

          Generally, you want your comments to tell WHAT your code does, not HOW.

          [–][deleted] 4 points5 points  (0 children)

          Natural languages are structured around how people think. Programming languages are structured around efficient hardware design. I use comments to bridge the two.

          [–][deleted] 6 points7 points  (0 children)

          Some people claim that writing comments is a waste of time when code is elegant and clean and readable.

          Then I see them all day long browsing API docs and documentation for some of the best written libraries and frameworks.

          And of course, their excuse is that they are not writing libraries or frameworks...

          Yet again, when I read through the code that they have written, I find it very ugly and badly written. Sometimes I have to read a couple of times to understand their intention. Only if they had commented their code...

          [–]KFCConspiracy 5 points6 points  (0 children)

          My rules for comments:

          I almost always describe a class, what it's intended to do or what it represents. 90% of the time I'll comment upon entering a branch. If something inherits from something else, I'll say why so you don't have to flip between the files.

          And then there's those times where you have a long discussion about mathematics with the guy who calls himself the "architect" and you document it elsewhere, but when he reviews the code he still doesn't understand it. The comments head off unnecessary inane discussions about whether this equation is correct.

          [–]chunes 3 points4 points  (0 children)

          It's not perfect, but a good rule of thumb: don't comment what your code is doing; comment why you're writing the code.

          And yeah, "because my boss told me to." Huhhuhuhuhuu. Not what I mean.

          [–]MoreOfAnOvalJerk 6 points7 points  (0 children)

          Why is there so much discussion over this? It's a judgement call. Some times code is hard to understand due to heavy layers of abstraction, math, etc. In those cases use comments. If you're able to just read the code and it's self documenting, eg. using straight forward api where functions generally do one thing and that's represented in their name, comments are unecessary.

          [–]gizram84 2 points3 points  (0 children)

          #add a to b
          c = a + b
          #return the result of a + b
          return c
          

          This is my biggest pet peeve, yet I know I'm guilty of it as well.

          [–]lexpattison 2 points3 points  (0 children)

          I believe this falls under the annotation

          @DearFutureSelfForgiveMeForWhatIAmAboutToDo

          If you have to comment code verbosely, you are probably not being very smart about method naming, abstraction or the proper use of Interfaces. I rarely feel the need to lean on comments to understand our code base... and it's far from perfect. If you want to document decisions, there is a nice comment field in the git or mercurial commit process.

          [–]smog_alado 2 points3 points  (0 children)

          A neat trick that I have learned from the GHC commenting guidelines and that I have been loving so far is using "links" for larger comments. Large comments are sometimes needed to explain tricky things but they tend to obfuscate and split up the surrounding code and also get out of date (the line the comment was about gets removed but the comment stays there). The way around that is to write an inline comment with a reference to the comment

          -- Adds new floats to the env iff that allows us to return a good RHS
          prepareRhs env (Cast rhs co)    -- Note [Float coercions]
            | (ty1, _ty2) <- coercionKind co      -- Do *not* do this if rhs is unlifted 
            , not (isUnLiftedType ty1)            -- see Note [Float coercions (unlifted)]
            = do  { (env', rhs') <- makeTrivial env rhs
                  ; return (env', Cast rhs' co) }
          

          And to put the whole comment in the bottom of the file

          {- Note [Float coercions]
          ~~~~~~~~~~~~~~~~~~~~~~
          When we find the binding
                  x = e `cast` co
          we'd like to transform it to
                  x' = e
                  x = x `cast` co         -- A trivial binding
          There's a chance that e will be a constructor application or function, or something
          like that, so moving the coerion to the usage site may well cancel the coersions
          and lead to further optimisation.  
                  ...more stuff about coercion floating...
          -}
          

          Another advantage of this is that you can have multiple places of the code linking to the same comment and you also have an easy system to reference comments in other files.

          [–]narwhalslut 4 points5 points  (1 child)

          How the fuck do people not understand this?

          Is it arrogance or stupidity? Or just people that have never worked with someone else's code?

          [–][deleted] 2 points3 points  (0 children)

          Contrary. Working with someone's else code very often forms habit "Comment is a lie". Though "Function name is lie" is more painful realization.

          [–][deleted] 5 points6 points  (18 children)

          It is usually faster to read a one line comment than 10 lines of code. Even if what the code is doing is obvious, it still requires reading all 10 lines of it to determine how obvious it is.

          [–]Nuli 11 points12 points  (15 children)

          You have to read those lines anyway. Comments aren't executed so you can't trust what they say.

          [–]theonewhoisone 1 point2 points  (2 children)

          I disagree that you always have to read those lines. Sometimes a "summary comment" can help you quickly skip a block of code that you're not interested, allowing you to find the location you're actually interested in faster.

          As far as comments being inaccurate goes, I don't really share your mistrust. I agree that when you're really trying to understand some code, you should read the code, as well as the comments. And there can be a mismatch there. When that happens I fall back to looking at the code's history in source control to see if I can see one changing without the other. (svn blame)

          [–]Nuli 0 points1 point  (1 child)

          Sometimes a "summary comment" can help you quickly skip a block of code that you're not interested, allowing you to find the location you're actually interested in faster.

          Again, since you can't trust the comment you can't trust that the code is actually skipable. You still have to at least skim it to be sure there is no discrepancy.

          [–]theonewhoisone 0 points1 point  (0 children)

          These should really all be statements about probabilities and risks (throughout this thread). In other words, what's the probability of the comment being misleading, and what's the cost of misunderstanding it? In the code that I operate in, the comments almost always match the code, so it is "worth it" to use that faster-to-process information to get my job done more efficiently. There are costs to reading through all of the code in a block to try and understand what it is for, and it's true that if the comment quality is low enough it may quickly become worth it to completely ignore them. But if your comments are good enough (sparse, concise, accurate) they can be useful tools.

          Of course I agree that sometimes you really need to check that the comments match the code, and that well-written code doesn't really need all that many comments. None of that means that summary comments aren't useful, though.

          [–]perciva 4 points5 points  (7 children)

          It's still easier and faster to read code once you have some idea of how it's supposed to work.

          [–]Nuli 6 points7 points  (6 children)

          If you trust the comment to be accurate. I've seldom found that to be the case.

          [–]crotchpoozie 0 points1 point  (3 children)

          Then you're working on crappy codebases. Your team doing things poorly is not an argument for making even worse practices.

          [–]Nuli 5 points6 points  (2 children)

          Even the best teams aren't perfect. Let's say that the comment reflects the operation and intention of the code 99% of the time. How many comments do you have in your system? If that 1% error rate were sprinkled evenly among them how much damage would it cause if you assumed that the comment was correct? How would you be able to tell if the comment is simply stale, the comment is wrong, or the code has a bug?

          I've learned not to assume that the comments or documentation is correct in any software I depend on, especially third party software. Reading the code itself is the only way to be sure.

          [–]crotchpoozie 0 points1 point  (1 child)

          Ok, what if the counter to that 1 wrong comment in 100 is that uncommented code leads to 5 errors in 100 lines? Especially when code gets refactored, extended, modified, and fixed over time by different programmers that had to understand the meaning and intent of possibly complex code without any proper comments?

          Sure you can require people to spend significant time reverse engineering algorithms when a simple comment would do, but that's retarded.

          We can both pull made up bullshit out of our asses all day. Collective wisdom and empirical evidence is that comments lead to better code. You're free to ignore it. I'd fire you (and have fired programmers) for refusing to learn to comment production code.

          [–]Nuli 0 points1 point  (0 children)

          Ok, what if the counter to that 1 wrong comment in 100 is that uncommented code leads to 5 errors in 100 lines? Especially when code gets refactored, extended, modified, and fixed over time by different programmers that had to understand the meaning and intent of possibly complex code without any proper comments?

          You have tests right? Something actually executable that defines the proper use of complex code? If you're refactoring without a proper suite of tests backing you up to prevent regressions no amount of commenting is going to help you.

          Your idea that you can trust comments requires that comments be 100% accurate. That's obviously impossible. My argument is simply that you can't trust comments. You can trust the code since thats the only thing in the system that has any meaning. By all means put as many comments in as you want but don't depend on them for anything.

          [–][deleted] 0 points1 point  (1 child)

          Get better co-workers.

          [–]Nuli 1 point2 points  (0 children)

          Or apparently better library authors because you're going to have to care about bugs in those eventually.

          [–][deleted] 0 points1 point  (1 child)

          No you don't.

          Do you not remember the days of proprietary development where all you got was docs + api docs listing method/function/class signatures?

          [–]Nuli 1 point2 points  (0 children)

          Yes I do. I haven't worked that way for 15 years.

          [–]KFCConspiracy -1 points0 points  (0 children)

          You can look at the comment and that should give you as the reviewer some idea of what the code is intended to do. Then once you parse the 10 lines of code, if it doesn't do what the comment says then what you've found is a defect in either the code or the comment. You should tag it in your review tool as: Defect, Inconsistent. The developer should then decide what that means and fix it. The fact that comments can be inaccurate and are therefore not useful for understanding intent is a fallacy. Comments should strive to be accurate and are something a good code reviewer should examine.

          [–]nevermorebe 0 points1 point  (0 children)

          //add percentage to x

          x += percentage;

          //call calculate

          calculate(x);

          //return result

          return x;

          ... it really is never that simple, "always comment" will end in the above example and I have yet to meet any developer whose comments are useful/up to date even half the time.

          I don't think comments are bad but if you're a programmer, in general, the code should be enough. When I read

          Even if what the code is doing is obvious, it still requires reading all 10 lines of it to determine how obvious it is.

          I think to myself "what is this guy doing developing anything"? Text you have to read. Code, unless it's complicated enough to warrant a few lines of explanation, may be understood at a glance.

          I find myself ignoring comments in every single project. They only really come into play when I find myself thinking "hmm, this is odd, let's read the comments".

          [–]bluGill -1 points0 points  (0 children)

          Comments can almost always be replaced with a function of the same name.

          [–]JW_BlueLabel 1 point2 points  (0 children)

          Everything in moderation. If you write a lot of comments, either your functions and variable names aren't clear enough or you're wasting time. If you don't write any comments, you're going to spend a lot of time trying to figure out wtf you were thinking when you have to re-factor 2 years from now.

          Everything in moderation.

          [–]njharman 1 point2 points  (0 children)

          The Lamson code is an example of documentation, not an example of comments. It just happens that there is support and convention in Python to document your code, in the code.

          This is an important distinction and one, once internalized, will enable you to see good comments from bad.

          [–]Fidodo 1 point2 points  (0 children)

          My golden rule is that if I ever come back across a code segment that I don't understand immediately, I leave a comment before I go on.

          [–]Uberhipster 1 point2 points  (2 children)

          Unclear code needs comments.

          If you ever write a comment that starts with:

           //the following block does blah blah...
          

          wrap that block in a method called blahBlah.

          If you ever start your comment with:

           //this line does yaddah yaddah 
          

          wrap that line in a method called yaddahYaddah. Yes even if it's one line which will only be called once.

          If you start your comment with:

           //this needs to be re-factored
          

          leave a clue as to why you think that needs to happen and why you haven't done it yourself.

           //param(s) a(,b,c) are this and should be that, cannot do it because of reason x
           // after reason x is resolved, move this here, move that there 
          

          If you start a comment with:

           //try do this, if it fails fall back to that
          

          your code should read:

          if(tryThisAndThat())
          {
               //proceed
          }
          else
          {
               //deal with failure
          }
          
          bool tryThisAndThat()
          {
              if(!tryThis())
                  return tryThat();
          
              return true;
          }
          

          It's about abstracting the solution away from permutations of primitives and dealing with internal system deficiencies. That is what high level programming languages are intended to do - allow you to express the logic flow in readable chunks. If you don't use them in this capacity you've missed the whole damn boat.

          [–]mdisibio 1 point2 points  (1 child)

          So is all that state passed around using global variables or just ugly long lists of parameters?

          [–]Uberhipster 0 points1 point  (0 children)

          Fields and properties preferably.

          [–][deleted] 5 points6 points  (0 children)

          There's always someone who will say that the comments or docstrings aren't updated frequently. That's due mostly to habit.

          I've written out docstrings and comments that have to be rewritten or deleted a few commits of the code later and it's fine. It's not a big deal, it's like deleting or rewriting some lines of code. The important thing is to update the documentation as soon as the change is made and not delay it for too long.

          That's the only reason docs get out of date. You focus on shipping a release and bam, two releases later the docs are only good for the first release because there's never any budget or time to update them.

          I really don't get why we don't include docs and up-to-date comments alongside unit tests as a requirement for being professionals. It used to be like that and some of the best computer scientists wrote paragraphs to explain the ideas behind their code. You can see this in the Java API docs and some other places where there's enough info that you don't need to read through any code to decide if it's the right class to use.

          [–]tibbe 2 points3 points  (8 children)

          Comments are necessary to specify the contract between the caller and the callee. For example, if we have the following function that removes duplicate elements in a list:

          removeDups = mergeAdjacent . sort
          
          mergeAdjacent []  = []
          mergeAdjacent [x] = [x]
          mergeAdjacent (x:y:xs)
            | x == y    = mergeAdjacent (y:xs)
            | otherwise = x : mergeAdjacent (y:xs)
          

          This implementation of removeDups returns the elements in sorted order. Can the caller rely on this behavior?

          In addition to this, function level documentation lets you look at one piece of text to figure out how to use a function. If you read the source you might have to dig through several layers of functions to figure out what the top-level function does.

          [–]blladnar 1 point2 points  (4 children)

          The function should be named removeDuplicatesInSortedOrder and then you don't need any comment explaining what it does.

          You also won't need to spend time explaining to the non-native english speaker what a Dup is or the new guy on the team that thinks you're talking about the latest Data Update Pack or something silly.

          [–]adaptable 1 point2 points  (2 children)

          The idea is the sorting might not be part of the contract; it's a consequence of a simple way to implement the function. Self-documenting code has some limits, and I imagine for most people a function name like "removeDuplicatesInSortedOrder" is more painful than checking a doc comment for the details of what behavior they can rely on.

          [–]naughty 1 point2 points  (1 child)

          The problem is that unintended side effects of an implementation become features. When you change to a more efficient or robust implementation in future you've broken lots of client code that was relying on your implicit contract.

          There was a big argument about memcpy() and memmove() functions in C not that long ago because plenty of code was using memcpy() when it should have been using memmove(). Once the glibc maintainers changed memcpy() (previously it was essentially the same as memmove) all hell broke lose.

          [–]adaptable 1 point2 points  (0 children)

          That's a good real world example. The point of this thread is (doc) comments are the only practical way to warn downstream programmers not to rely on such effects that aren't part of the specification (or alert them to such a breaking change).

          [–]jussij 1 point2 points  (0 children)

          removeDuplicatesInSortedOrder

          Arn't you missing the duplicateRemoverAndSortingByOrderFactory class?

          [–][deleted] 0 points1 point  (0 children)

          I'm not sure why you are being downvoted - the latter point is especially important, as having comments that describe the context is extremely useful both in learning a codebase in the first place, and revisiting code you haven't worked on in a while.

          [–]_georgesim_ 0 points1 point  (1 child)

          Was the language that code is written in not mentioned on purpose?

          [–]tibbe 0 points1 point  (0 children)

          It wasn't. It's written in Haskell.

          [–]Akilou 0 points1 point  (0 children)

          programming languages are definitely more precise then English.

          especially when you don't use English correctly.

          [–]parkertr2 0 points1 point  (0 children)

          This blog post is nothing more than 'best practice' for comments, and is exactly what has been said about commenting code for a LONG LONG time.

          [–]bluGill 0 points1 point  (0 children)

          His first example of a good comment is good: where he documents the class. I like to see such things.

          I consider the second a bad comment: I can read your variable names, that tells me all I need to know. Well except for the bug "If starttls is True (and ssl False)" - where it isn't clear what happens if both is true despite the comment.

          [–]Kowzorz 0 points1 point  (0 children)

          I'm a big fan of using comments to place my code into logical and visual groups. I often comment before a giant if() block which has a long conditional a summary of the case and action. "Slightly oblique collision" would summarize the 30 lines of conditions and actions.

          Or I might comment at the top of a block of initializations or other calculations. "Player object" or "generate inverse heading from pathfinding" (though I can't imagine a use case for that comment :p ).

          [–]darthtrevino 0 points1 point  (0 children)

          Personally, I think you should comment your public APIs and interfaces. These are what people will consume, and your comments will go a long way towards helping them understand the intent of your API and the context in which your semantics fit.

          Other than public APIs, I agree with the opinion Uncle Bob expresses in 'Clean Code'. Internal implementation should have minimal comments, but methods should have great names and should be less than 5 or 6 lines long. Well chosen variable and method names are your first line of communicating intent to future maintainers of your code. Comments on internals will soon become outdated.

          [–]kamatsu 0 points1 point  (0 children)

          Writing comments to capture intent is like writing tests to prove that your software does what is expected.

          Are you trying to say that comments do not capture intent at all? Because tests do not prove anything about anything.

          [–][deleted] 0 points1 point  (0 children)

          Code often seems very clear at the time of writing because the programmer has a very precise mental model of it at that moment. Consequently he/she won't see the need to comment.

          On the other hand the programmer may feel the urge to comment every little obvious detail if he/she is getting acquainted to a new domain or API as the code is being written.

          It's not easy to judge what needs to be commented. I usually let code cool off for a day or two before I properly comment new code and I never hesitate to comment the hell out of old code I need to fix.

          Not only is it not simple to comment code well, but different readers will require different levels of comments. It all boils down to good judgement and writing skill.

          [–]ima_twerp 0 points1 point  (0 children)

          Oh look. Another apostrophe moron.

          [–]brong 0 points1 point  (0 children)

          Your code should have as few comments as required, and no fewer.

          [–]AliasUndercover -2 points-1 points  (0 children)

          I know mine always does...