Hacker News new | past | comments | ask | show | jobs | submit login

Honestly, I would add this whole comment to the list of "absolute truths" juniors unlearn as they get more experience. And I would also point to the original post's point that types of experience matter - just because you're early 30s doesn't necessary mean you've had the right experience. If you still believe this, then - to be brutally honest - I would question the quality of the teams you've worked with.

Comments don't have to decay. Discipline is important. Culture is important. And yes, these have to be intentionally set and upheld.

If you set a culture of discipline around maintaining the comments with the code, and ensuring they are updated, then it's really not that hard to do it. If the developer doesn't remember to do it when making changes, then the code reviewer can catch it and enforce it.

And nothing really substitutes for an english language explanation of the "why" and the intention of a particular section of code. A good comment explaining why something was done a particular way, or what the code was intended to accomplish, can save hours of walking up and down call stacks. It's also something that cannot be communicated through unit tests, or even integration tests, a lot of the time. Those communicate the "what" and the "how" - not the "why".




> Comments don't have to decay. Discipline is important. Culture is important. And yes, these have to be intentionally set and upheld.

These are things that are often completely outside your control.

> If you set a culture...

At most shops, you don't get to set the culture. About the only time you do is if you're a founder or early developer. Otherwise you have to fit into the existing culture, or attempt to find a company that better reflects what you want. Sure, it's not hopeless; you can likely influence to some extent, but your influence is usually limited.

> And nothing really substitutes for an english language explanation of the "why" and the intention of a particular section of code.

I do agree with this. Any code that can't be written in a self-documenting way absolutely must be commented. However, if you find the need to do this often, it might be a sign that you should focus more on code clarity and less on (likely premature) optimization, or perhaps consider if you're really using the right tool (language, framework, etc.) for the job at hand.

I will admit that I probably comment less than I should, but I feel like the average is way too verbose, and that enough comments are out of date and incorrect (often in very subtle ways) that it adds significantly to my overhead when trying to understand someone else's (or even my own) code.


> If you still believe this, then - to be brutally honest - I would question the quality of the team's you've worked with.

To be equally brutally honest: right back at you. I would trust the quality of those I've worked with over those who believe in comments, any day of the week.

My point was simply that I started as a believer in comments when I was more junior, and became anti-comment through experience. So even if we believe senior people are more likely to be right than junior people (which I very much doubt, frankly), that tells us little about whether comments are good or not.

> If you set a culture of discipline around maintaining the comments with the code, and ensuring they are updated, then it's really not that hard to do it.

Human programmers have a limited discipline budget, and if you're spending it on keeping the comments up to date then you're not spending it on other things. Yes, you can use manual effort to keep code explanations up to date, just as you can use manual effort to ensure that you don't use memory after it's freed, or that your code is formatted consistently, or that the tests were run before a PR is merged. But you're better off automating those things and saving your manual effort for the things that can't be automated.

> And nothing really substitutes for an english language explanation of the "why" and the intention of a particular section of code.

Disagree; code can be much more precise and clear than English, that's its great advantage. As the saying goes, the code is for humans to understand, and only incidentally for the computer to execute. The whole point of coding declaratively is that the "why" is front and center and the "what"/"how" follows from that.


> The whole point of coding declaratively is that the "why" is front and center and the "what"/"how" follows from that.

I've been writing Lisp off and on since late last century, so I know full well the value of declarative code. Preaching to the choir, there! But I can also report that every real program I've ever written (i.e., that had at least one user) needed significant non-declarative parts.

And for those non-declarative parts, you need the "why". Why is this call before that one? Why is this system call used? Why is this constant being passed to the call? And so on. (It's because when you run it on OS ${a} version ${b}, there's a bug in the ${c} library that requires us to force the initialization of the ${d} subsystem before it can ... true story.)

The declarative parts of your program don't require "why" comments, and that's great, but a corollary to that is the parts that can be written in a declarative style aren't the ones that require a "why". Building a DOM structure manually takes a lot of lines of code, but it's all still quite simple, and requires no explanation. Writing a trampoline necessitates a bunch of "why"s, and there's no way to just substitute a declaration for it (without pushing the whole mess somewhere else).

Code is first for humans to understand, and that requires comments, because humans speak English (or some other natural language), and no programming language is yet powerful enough to efficiently (in time or space) express everything that English can.


> Writing a trampoline necessitates a bunch of "why"s, and there's no way to just substitute a declaration for it (without pushing the whole mess somewhere else).

I've got a trampoline in my codebase to avoid a stack overflow. The why is the test that a certain repeated operation doesn't stack overflow.

There are a number of places where it could've been implemented with one technique or another, but there's no particular reason that the approach I've taken should be better or worse than one of the other options. If there was, I'd want to formalise that (e.g. if I'd chosen one approach because it performed better than another, I'd want a benchmark test that actually checked that).


> code can be much more precise and clear than English,

This doesn't address the parent's criticism. Clear, precise code only tells you what the computer is doing. What it can never tell you is why the computer needs to do it exactly like that.

Software breaks in weird ways when pushed to the limits. The fixes for these edge cases are not always obvious and may not be something that can be replicated with testing.

Without comments, some cowboy can come along and think, "it's flushing a buffer here? that's dumb. <delete>" The change gets put in, passes testing, spends four months in production, when a bug report comes in from a customer complaining about an issue that they had three years ago.

Now someone has to spend a bunch of time figuring out the problem, QAing the fix, then getting it back into production. It's thousands of dollars that the company could have saved if only there was a comment about why that buffer flush was there.

You might think this is some crazy edge case, but it's not.


This is my problem as with this argument as well. English and other spoken languages seem first and foremost about conveying ideas. Programming languages seem first and foremost about conveying instructions to computers that don't comprehend "ideas"..

Reconstructing the original idea or meaning can often involve far more context than local variable and functioning naming can provide.


I don't understand what sort of environment you work in where you don't encounter situations where comments could add clarity to the code.

Do you never see code that has global side effects? Or that is written a particular way to take advantage of the hardware that it is running on? Or any other of the many ways that the intention and meaning of a piece of code within the codebase it exists in can be not immediately obvious?


>Do you never see code that has global side effects?

The answer for modern languages and frameworks is "write pure functions."

>Or that is written a particular way to take advantage of the hardware that it is running on?

Move to service/helper/utility class for that particular hardware or with a name that clarifies it's for that particular hardware.

I find comments to be necessary very rarely. Atm looking at a codebase where they are made to cover up for a lack of desire to think.


> The whole point of coding declaratively is that the "why" is front and center and the "what"/"how" follows from that.

Declarative means that we specify the "what", and the machine deduces the "how".

There is no room for "why", because our present-day machines do not require motivating argumentation in order to do our bidding. They either need the "what" or the "how", or whatever blend of the two that we find convenient.

We need the "why" in the documentation. Such as: why is this program written in the first place? The "why" is not in the code. When code is clear, it's just easy to understand its "what" or "how", never the "why". Unclear code obscures the "how" or "what", but clear code doesn't reveal "why".

Every "how" breaks down into smaller steps. Of course, those smaller steps have a "why" related to their role in relation to the other steps; that's not the "why" that I'm talking about here. Of course we know why we increment a loop counter when walking though an array: to get to the next element. If you start commenting that kind of why, you will soon be flogged by your team mates.


code can be much more precise and clear than English

Agreed, code is much more precise than English. But precision is not the same thing as being meaningful and without context, precision is useless. Code generally sucks at context, which is why every programming language worth its salt has comments.


You are missing the point entirely. No matter how clear your code is, it is only expressing the “what”, not the why. I can see that you’re using a binary tree, but why a binary tree and not a hash table? Why a decision forest and not a linear regression? Why a regularization penalty of 0.1 and not 0.2? Why cache A but not B? Why create an object at startup instead of generating it on the fly? You need comments to explain these decisions.


If there's an important difference (e.g. a performance requirement that a hash table wouldn't meet), I'd have a test that checks that. If not, it's probably an arbitrary choice that doesn't matter. If the decision is worth recording, it's worth recording properly.


For the cases you mention a combination of package name, class name and method / function name could serve as a comment with the benefit of making sure any place referencing the code also "documents" why something is happening (tests for example, or callers of your methods).

This is not always possible, and in those cases I also strongly prefer well written, concise comments explaining what is going on and why, ideally with a link to a reference/source which explains the background.

Some examples of method names:

- generateTreeToAllowPartitioningOfItems(...)

- getMatchingRegularizationPenaltyForSpecialCaseX(...)

- getShortTermRedisProxyCache(...)

- createNewPrefilledTemplateObjectForXYZ(...)

I hope this doesn't sound snarky. But more often than not comments do date in my experience (and they don't handle refactoring well), while (compiler-known) names are handled as 1st class citizens by the current IDEs and thus are corrected and updated anywhere.

In code reviews we usually aim for "low comment" density, the implementer shouldn't explain what or why he was doing, the reviewer has to understand just from the code (as it would happen if she/he has to maintain it later on). The review is "not good" or even fails if the reviewer doesn't understand why and what is happening. The outcome will in most cases be an improved design, not more comments.


But those method names are still hard to relate to the business cases your customer requested. So you implemented something for some reason; your code and methods tell you what you implemented but not why... Why did you use a tree? I read your top level code and think ; dude, that would have been so much simpler and faster using a Wobble instead of a Tree! Then I try that and it turns out it has to be a Tree; you went through the same process, did not tell me why and I lost a day retrying. For instance.

(assuming, which you should always assume imho, that you left the company many years ago when this event occurs)


If I wrote an explanation then what would check that explanation? Maybe I write "we use a Tree instead of a Wobble because Wobble doesn't support the APIs we need". But then maybe when you come to work on it, it turns out that the current version of Wobble does support those APIs. Maybe it's actually better at them than Tree. Whereas if I have a unit test around Tree that exercises the kind operations that we need to do, then you can just try dropping Wobble in there and see for yourself whether it works or not.


> code can be much more precise and clear than English. [my emphasis.]

As a common feature of most higher-level languages is that they co-opt natural language terms (and also mathematical notation, which is an option in commenting) with the intent to increase clarity, can you show us an example where code is more clear than natural language in explaining both what it is doing and why?

If you are working in something like APL, I can see there might be a case...

I am not so much interested in the precision issue, as both code and language can be very precisely wrong or right.


> Human programmers have a limited discipline budget

You think humans are bad, try working with Lobster programmers, they get work done, but their coding style is just horrible (they use tabs).


>If the developer doesn't remember to do it when making changes, then the code reviewer can catch it and enforce it.

They can. Just after correcting all the buffer overflows and before fixing all the use-after-frees. Then the comments can be consumed by all the other teams with the discipline and culture to avoid writing bugs for all time.




Registration is open for Startup School 2019. Classes start July 22nd.

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

Search: