Readit News logoReadit News
renhanxue · a year ago
I saw someone quip (on twitter, I think) many years ago something like:

"A junior engineer writes comments that explain what the code does. A mid-level engineer writes comments that explain why the code does what it does. A senior engineer writes comments that explain why the code isn't written in another way."

(except punchier, of course. I'm not doing the quip justice here)

kwhitefoot · a year ago
> writes comments that explain why the code isn't written in another way."

Exactly! I have written code that required comments five times as long as the code itself to defend the code against well meaning refactoring by people who did not understand the code, the domain, or the care needed to handle large dynamic ranges.

I have also written substantial functions with no comments at all because it was possible and practical to name the function and all the variables so that the meaning was clear.

yxhuvud · a year ago
I've also written that kind of comments, and then promptly had it refactored by people not reading comments.
abc-1 · a year ago
I do all of the above. Summary comments are incredibly helpful and have been validated by empirical research. Too bad many have drunk deeply from the Clean Code koolaid and can’t be saved.
hughesjj · a year ago
I got some flak at a prior job for saying I had some quibbles with clean code (a few years after I had read it), and I'm glad this opinion is more popular today. There's so much cargo culting hype with "best practices" and style, I hate it. Same with how overly dogmatic people were with OOP paradigms when it came out (remember using anonymous interfaces to pass a function around in java?). Same with the functional backlash to that.

It's fun and enlightening to go ham on any particular style/framework/philosophy, but actually living by dogma in prod gets kinda dangerous and imo is counter to the role of a senior+ engineer

Prickle · a year ago
I was taught to not leave comments in finished code.

I have regretted following that lesson ever since.

appplication · a year ago
Yes I write comments like a maniac. Long doc strings that are informally written. It’s more important for me to say what I need someone else (or future me) to know about a function and its context than it is for me to have some beautiful, sterile 300-line autogenerated soulless docstrings.
__MatrixMan__ · a year ago
I like two of the three, but what is the advantage of commenting what the code is doing, when you can use a Trace or Debug message for that instead?
cjfd · a year ago
This 'empirical research' is highly doubtful. The first question to ask is what the code with summary comments looked like. While summary comments can sometimes be helpful, this is mostly the case in functions that are relatively long. A question that always arises in that case is whether it is a good idea to split them instead of commenting.
seanmcdirmid · a year ago
We could have the best of both worlds if comments could be easily hidden, or better yet, just additional meta-data on rich text code. But nope, we can't get away from ascii.
cesaref · a year ago
Junior programmers tend to either document nothing, or document everything. With experience you realise that you just want to document the unusual stuff, and as you get more experienced, you realise there is less and less unusual stuff, so the amount of comments drop down.

So, less comments wins out, but faced with a code base without comments you have to inspect it to tell the difference between a beautifully crafted piece of brilliance or a totally flaky codebase written by a bunch of newbie hacks.

lawn · a year ago
> and as you get more experienced, you realise there is less and less unusual stuff, so the amount of comments drop down.

This is a common experience when I use a new language or framework. At the start I comment a lot of things because I think it's useful for future me, but as I learn more I realize that many of the comments are redundant so I end up removing them.

andoando · a year ago
You have to consider who the comments are for. Senior engineers comments are more useful for senior engineers, but the junior comments will be more useful for junior engineers.
steveBK123 · a year ago
There's also the comments that tell you why the code does something obviously stupid but needs to continue replicating this stupid behavior because something else depends on it behaving this way.
saurik · a year ago
That sounds like "explain[ing] why the code isn't written in another way" where the other way is "the way you are right now thinking it should be as you read this: the way that isn't obviously stupid".
paulryanrogers · a year ago
This is the way :mando:

If it's not answering why or at least providing a very concise how to very verbose code, then it's just adding noise

mschuster91 · a year ago
> A senior engineer writes comments that explain why the code isn't written in another way.

And C-level engineers write a comment "X hours have been wasted on refactoring this code. Should you decide following the example of your priors, please increment this counter."

Sometimes, even what appears to be an utter hack job actually is the best you're gonna get.

wrwatson · a year ago
I think of comments as an apology to the engineer reading the code.

I'm apologising because the code isn't obvious, or the language not sufficiently expressive, or the good-idea-at-the-time no longer is. Ideally I wouldn't need to write many comments, but I often find myself sorry things are not simpler.

atoav · a year ago
In the end a comment should be like a shortcut that allows people to understand your code faster or a reminder why certain choices were made.

You are right in spirit to say sorry when the code cannot be self-explainatory, but consider that sometimes even if the code is self explainatory, comments can help your reader to see the grand picture faster or to avoid interpersonal ambiguity by allowing you to use two different ways of phrasing a thing.

belorn · a year ago
I find that purpose of comments is to give context to the written code. Sometimes the context explains what the code does, and more often it explains why, but the best comments gives me the reader an insight so that I can have a intuitive feeling for what the author are writing.
anotherevan · a year ago

    Cursor cursor = getCursor(); // Cursor.

erik_seaberg · a year ago
I have seen a linter that requires

  class User {
    public String getName() { ... }
  }
to have a doc comment explaining what getName does and also what it returns. Before git, they sometimes needed to see who wrote it and when.

retrochameleon · a year ago
I resonate with that example. It's usually about a piece of code that didn't turn out the way you wanted to due to an issue. If there's a literal github issue or source I can link, I'll include the URL in case someone checks later and it's no longer a blocker.

Somethings I include brief explanations or links to a particular piece of hard-to-find documentation.

david-gpu · a year ago
> A senior engineer writes comments that explain why the code isn't written in another way

I suggest providing that sort of high-level decision information in a separate design document. This sort of documentation is written before the code and is presented/discussed with management and peers.

That is how it was done at a couple of companies I worked at and it was very effective. Naturally, this was done at the feature level, not on a function to function basis.

bccdee · a year ago
Then you end up with a design document that corresponds to the code as it existed conceptually before v1 of that code was even written. By the time v1 is written, the design doc will be slightly out of date; by the time the code reaches v3, the document is more than 2 versions out of date.

The nice thing about comments is that they're in the code. You can't update the code without at least looking at them; that's more visibilty than you'll get from anything else.

solidninja · a year ago
That still needs discipline though - or you end up with N half-finished Confluence pages describing the intention behind the design, all of which are now out of date (and naturally in completely different places). The best way I've seen to keep track of changing things is to have the design linked to the ticket somehow (and if it's a link, then that needs to be a permalink to something that will not go away in a year's time).
zo1 · a year ago
I really have to push back against this "design document" stuff. Unless you're writing some sort of uber-complicated, mission-guidance-systems-level code with multiple standards and audit compliance and and and, then you don't this.

Alternatively, if your org or reach for this feature is so large that you need to communicate and decide its internals with a lot of people and as such require something like a design document, then you've already failed and you have way too-many cooks in your kitchen. Design by committee is always doomed to failure.

Thirdly... if you need a design document to communicate your feature to "management" then that means you don't have autonomy to design this feature as an expert, and again, you have too many "fingers" in your pie.

Does this mean you should go into a basement and design your feature like a hermit? No, but a design document shouldn't be your answer, it should be a better team and process around you, as well as a clear business specification.

anhner · a year ago
I understood that to mean "I've tried doing it x way and it didn't work because y." rather than the functional part. At that point, why not keep the documentation together with the code?
MyFirstSass · a year ago
True! Also i sometimes also do "yes this looks weird, but it's because : somebugtracker.issue"
incontrol · a year ago
When I feel the need to add a comment, I convert that piece of content into the named function.
kaoD · a year ago
So how do you document what is not in the code?
throwaway14356 · a year ago
...but if it is regex we are all juniors.
narag · a year ago
I comment everything that I think would be useful for me when revisiting the code a year later. Usually "why" and "why not". Sometimes a short "what" when the code is complex and it's nice to see the sequence more clearly.

What's not so useful: mandatory comments. A public API should be thoroughly documented, but some shops insist on writing comments for every function in the code, even private ones and even if its purpose is so obvious that the comment just rephrases its name. This practice is not only a waste of time, but also insensitizes you about comments and teach you to ignore them.

Other wasteful comments are added by some tools. I hate the one that marks every loop wiht a //for or //try comment.

Cthulhu_ · a year ago
For some reason a lot of syntax highlighting color schemes de-emphasize comments, making them low contrast, which is probably because a lot of mandatory / generated comments are low information. Get rid of mandatory and generated comments, and change your color scheme to make them a bright neon colour instead (on a dark theme) to draw the attention, because IF something is commented then it's important.
dizhn · a year ago
I disagree with this. Comments are important but not every time you're in that part of the code. You might already know from just the code what's going on, or have already checked out the comments. There's no value to them always being emphasized. That would be like reading all NPC dialogs every time in an RPG.
gspencley · a year ago
> I comment everything that I think would be useful for me when revisiting the code a year later.

Do you code solo or do you work with a team? If so, how large is the largest team you've worked with?

I used to be a dogmatic "all comments are code smells" person and, to a large degree I still am. But working on a very (and I mean VERY) large code-base that is actively developed and maintained by hundreds of other software developers, I have relaxed my position slightly into the "if you need to do something weird, explain why" ... because a large legacy system that lives in a business environment of tight deadlines means that there are often weird things that need to be done to keep things moving at a pace that the business is willing to pay for.

Anyway, one of the many reasons that I argue AGAINST code comments is that the comments become part of the code and therefore require maintenance. But few people read comments unless they are stuck trying to understand something. This "psychological invisibility" is even enforced by the fact that most code editors will grey out comments in order to make them less distracting.

And therefore, comments can easily become outdated.

So I'm curious about your situation. Since you say that you like to give yourself useful context for "future you", what context does this process serve? Do you find it useful when working on a shared codebase with lots of other developers? Or is it something that only works well when there are few developers touching the code?

RHSeeger · a year ago
> And therefore, comments can easily become outdated.

I am firmly of the opinion that keeping the comments up to date is part of the job of the developer. And if they're not doing it, they're not doing their job. It's no different than taking the time to write code that does the right thing, expresses the intent of what it's trying to do, etc. And, when code is peer reviewed, not including/updating comments in places where they are important should be a reason to send the code back to the developer.

I feel the same way about automated testing. They're both (testing and comments) way to make our code better; easier to understand, easier to maintain, more likely to be correct, etc.

mplewis · a year ago
Comments that I leave for myself help remind future-me why I did something that otherwise looks confusing.
ziml77 · a year ago
I think color schemes that make comments nearly invisible are just bad. Visual Studio's default color schemes have it right. Comments are not treated as lesser than anything else.

As long as they aren't being placed every couple of lines they shouldn't really be a nuisance when reading through code.

And to me not updating the comments is the same as not updating the name of a variable when its purpose changes. The compiler doesn't care that you didn't update the name, but people reading the code do.

Also when it comes to "future you", you basically should think of yourself in the future as a different person. Because unless you are constantly working with the same bits of code, you will forget details and possibly even the high-level.

cjfd · a year ago
Yes, completely agree. Also, too many comments make it difficult to see what is in a class/function. If the comments make a class/function that would otherwise fit on one screen no longer fit on one screen there is a readability cost to this.
exe34 · a year ago
I wish they would put the comments before the function name in python, as otherwise the useful code is separated by useless verbiage. I also wish comments would include examples of the shape and dtype of inputs and outputs.
BeetleB · a year ago
Collapsing/hiding comments should be a required feature in editors.

In Leo[1], you can make nodes out of them and just hide them. If Emacs weren't so good, I'd be using Leo. Similar power when it comes to extensibility, but extended via Python, not elisp.

[1] https://leo-editor.github.io/leo-editor/

gwervc · a year ago
> Usually "why" and "why not"

Related anecdote: yesterday I was on a code portion of a personal project with a "Is this really useful?" comment on a line that seemed it could easily be removed. I tried to use the newer and cleaner class instead and the particular old way was indeed needed. So I appended a "=> yes!" to the existing comment as well. I'm glad my former self documented the interrogation.

At work, especially on bugfix, I often write a one or two lines comment with the ticket issue number over a non-obvious change.

danadam · a year ago
> So I appended a "=> yes!" to the existing comment as well.

You will read it in 3 months and cry in despair "But why, my past self, why is it needed?!" :-)

Attrecomet · a year ago
> Other wasteful comments are added by some tools. I hate the one that marks every loop wiht a //for or //try comment.

Oh god, that's horrible, what kind of tool does that?!

skipkey · a year ago
It was pretty common say 25 years ago when you would be developing in a terminal. When you were limited in the number of lines displayed, it sometimes made it easier to follow the code when functions and control structures were large.

I know I had coworkers using brief configured to do that.

narag · a year ago
I don't know, the guy is no longer around. Maybe some code-completion tool (write "for" and it completes the syntax) because it's all over the place.
harry_ord · a year ago
I find the why and what are so useful. If I know why what the code is aiming to achieve, it makes rewriting it or fixing a bug much easier
anotherevan · a year ago
I think the favourite type of comment I've ever left in my code follows this template:

    DEAR MAINTAINER:

    This code is the way it is because of <reasons go here>.

    Once you are done trying to 'fix' this, and have realised what a terrible
    mistake that was, please increment the counter as a warning to the next
    person:

    total_hours_wasted_here = n
I'm not the original author, but have gratefully used it once or twice, and been amused when there was a single line commit incrementing the counter.

tombert · a year ago
I wish I had had this years ago.

I one time wrote this fairly elaborate SQL generation thing that required pretty liberal use of recursion in order to fulfill all the requirements. It ended up being a lot of mutual recursion and the code was admittedly kind of messy but it was a necessary evil to do everything asked of me.

A more senior engineer ended up taking over the codebase, "fixed" all my code to be this iterative thing, made a point to try and lecture me about why recursion is bad in an email, only for his code to not actually do everything required and him reinventing effectively everything I did with recursion.

In fairness, he did actually apologize to me for some of the comments he made, but if I had thought about putting this comment on the top maybe we could have avoided the whole thing.

bccdee · a year ago
I've never heard anyone say recursion is bad. What a weird view.

It's a problem if you're overflowing the stack, of course, but otherwise…

ghewgill · a year ago
I agree that the title is ambiguous - it's what piqued my interest to read the article in the first place. Personally I lean toward fewer comments overall - perhaps to a fault - but explanatory comments as shown in the article are absolutely valuable. It's a good reminder to explain the whys and the why nots.

This especially applies to your own code that you write and still have to maintain 5, 10, 15 years later. Just the other day I was reviewing a coworker's new code and thought "why choose to do it this way?" when the reason was 10 lines up where I did it the same way, 8 years ago. She was following the cardinal rule of maintenance - make the code look like the existing code.

sparrish · a year ago
> make the code look like the existing code.

This is so undervalued when maintaining an older codebase. Please, for the sanity of those who come after you - make the code look like the existing code.

sbuttgereit · a year ago
"Please, for the sanity of those who come after you - make the code look like the existing code."

I think it's a great rule of thumb... but there are exceptions.

For example, Funnily enough I was reviewing some code just today written by someone else and that I'm going to be asked to expand on or maintain. It looks like this:

  var example1 = Object;
  var example2 = Object;
  var example3 = Object;
  ...
  var example147 = Object;
  
And then later there are corresponding variables assigned to different objects which are:

  var tempExample1 = <some object instantiation>;
  var tempExample2 = <some object instantiation>;
  var tempExample3 = <some object instantiation>;
  ...
  var tempExample147 = <some object instantiation>;
And this goes on and on. It's real special once we get into the real business logic. (and to be clear... "example1" are the actual names, I'm not just obfuscating for this comment.)

The reason it looks like this is because the original developer copied the examples from the developer technical documentation for what they were doing verbatim; this documentation only had one variable so the numbering was the way to get multiple variables. Knowing this system, they didn't have to do that, they could have very easily assigned meaningful names for all of this. (To be fair, the original developer isn't a developer but a consultant business analysist saying, "Oh yeah, I can do that!" to the client.... billing all the way).

I can tell you with great certainty and righteousness: I'm not going to make my code look like the existing code. I may well do some refactoring to make the existing code vaguely scrutable.

I appreciate that what I'm describing is an extreme case and not really what you or parent comments really were addressing. I just stop to point out that what you describe is a rule of thumb... a good one... but one nonetheless. And, as an absolute rule of thumb about rules of thumb, there are no absolute rules of thumb. Ultimately, experience and judgement do matter when approaching the development of new code or decades old code.

Tainnor · a year ago
Unless of course you work in a wild-west codebase where you can basically tell who wrote what code because everyone has a distinct style and they never converge. ugh
Timwi · a year ago
This is just a special case of a broader, more general advice that I follow:

Comment on whatever would be surprising when you read the code.

When I write code, a voice in the back of my head constantly asks “will I understand this code later?”. (People who just instinctively answer ‘yes’ every time are arrogant and often wrong.) Whenever the answer is ‘not sure’, the next obvious question is “why not?”. Answering that question leads you directly to what you need to write in your comment.

Sometimes the answer is “because the reader of the code might wonder why I didn't write it another way”, and that's the special case this article covers. But sometimes the answer is “because it's not obvious how it works or why it's correct” and that clearly requires a different type of comment.

perlgeek · a year ago
As an addition, if you first try to write the code one way, and then it doesn't work and you need a second approach, that's a really good indication that you want some kind of comment there. You were surprised while writing it, so if you'll forget that surprise in a year, you'll be surprised by reading it too.
albrewer · a year ago
> “will I understand this code later?”

My driving principle in the same vein is "where do I have to look when/if this doesn't behave as expected?" - if the answer is not in the docs (wiki -> package/module -> file -> class -> function / method) or is otherwise > 10 lines away, it gets an inline comment (or the docs are updated). Usually this happens when chopping up strings or during intermediate navigation steps over an odd data structure.

gregmac · a year ago
> I see more people arguing that whys do not belong in comments either, that they can be embedded into LongFunctionNames or the names of test cases. Virtually all "self-documenting" codebases add documentation through the addition of identifiers.

Identifiers can go a _long_ way, but not _all_ the way. I personally am a fan of requiring documentation on any public methods or variables/fields/parameters (using jsdocs/xmldoc/etc). Having a good name for the method is important, but having to write a quick blurb about what it does helps to make it even clearer, and more importantly, points out obvious flaws:

* Often even the first sentence will cause you to realize there's a better name for the method

* If you start using "and" in the description, it is a good indication that the method does too much and can be broken down in a more logical way

People often think properties are so clear they don't need docs, then write things like:

    /** The API key */
    string ApiKey;
But there's so much missing: where does this key come from? Is this only internal or is it passed from/to external systems? Is this required, and can it be null or empty? Is there a maximum? What happens if a bad value (whatever that is) is used? Is there a spot in code or other docs where I could read more (or all these questions are already answered)?

This is stuff that as the original author of the code you know and can write in a minute or two, but as a newcomer -- whether modifying it, using it, or just parachuted in to fix a bug years later -- could take _hours_ to figure out.

JohnMakin · a year ago
I often write comments like this when I can predict what an overly nitpicky reviewer will say in a code review - "I didn't do X because Y" hoping to save some annoying back and forth about it.
lainga · a year ago
IME you get the same amount of back and forth but I get to write "as the comment says" a few times
JohnMakin · a year ago
LOL precisely
rplnt · a year ago
I add those preemptively in the PRs, but not sure they have much value in the code.
not2b · a year ago
They have value in the code because they save time when someone has to deal with that code a couple of years later. Certainly the explanation could be in the code reviews or the commit message, but it's easiest if it is right there.
Terr_ · a year ago
> Does 16 passes over each string BUT there are only 25 math strings in the book so far and most are <5 characters. So it's still fast enough.

Another twist on this is to put in a debug logging statement which triggers when the inputs are much larger than the original design constraints.

It's roughly the same message to a future-developer, but they might find it much sooner, short-circuiting even more diagnostic and debugging time.

ok_dad · a year ago
This is a great idea for a lot of things! Sometimes I will write a loop I know is slow as hell but works for now, and it would be cool to use a timer and do, "if this takes more than X seconds, log a warning." I mean, the perfect logging and observability should theoretically time all the components of your app, log debug information often, and etc., but who really uses a perfect system like that? I think it's more important to make specific effort to log in areas where performance might suck later or where you didn't have time to optimize or do exactly what you wanted to do.

Your comment is super obvious, in hindsight, but I never thought to do something like this, usually at past places of work we've just agreed to make a comment on things we need to reconsider later and hopefully we remember about that comment when things go downhill!

Terr_ · a year ago
I'd caution that it's a very "80/20" thing, since the cost/complexity of detecting all "unusual" cases can easily become not-worth-it.

For example, if the slowness of the method depends on non-trivial aspects of the input, or if the performance problem in production comes from someone calling your method too many times on (individually) reasonable chunks of data.

CRConrad · a year ago
> and etc

The "et" in "etc" means "and", so you have that already.

AlotOfReading · a year ago
I find that a lot of well-meaning tools (e.g. bazel) regard non-error output as noise to be hidden. They'll often route any messages like this to the nearest wastebin they can find, which makes logging incredibly unreliable as a means of communicating constraints in some domains.
Terr_ · a year ago
I'm thinking the log message is something you wouldn't want to trigger in production anyway, unless you're pretty confident that it won't lead to a ton of spam on the day that inputs rise over the threshold.

Using a debug log-level helps prevent that problem from occurring in production, while still making it visible to developers that have more logging enabled in their dev/test environments.