Hacker News new | ask | show | jobs
by kozak 3198 days ago
One of my most useful insights in software development is that no matter how smart you are, if you write code that can't be understood by a junior developer, it means that you didn't do a good job writing that code.
6 comments

And the reason that "the code is self-documenting" is a bad smell is because in 3 months even the 'rock star' who wrote it won't remember without appropriate help (eg comments).

I've worked with some pretty smart developers in some pretty interesting roles, and the people cock-sure of themselves are rarely anything other than a poisonous danger to overall performance and deliverables typically.

I say this as a lone wolf by inclination, though also unexpectedly happy on a trading floor with hundreds of people around not entirely managing their emotional interactions!

In my mind "the code is self-documenting" doesn't mean that you should have no comments anywhere in the code. It rather says that instead of lazily adding a comment for some complex piece of code, try to refactor the code so it better explains what is happening there.

And then sometimes, you just have some compiler-hack or otherwise complex piece of interaction that you can't refactor into something better, and then it's of course better to add a comment rather than just leaving it there.

Besides, code speaks to the compiler/runtime; comments speak to the human.

- The machine need to know HOW something should happen. That's code.

- The human needs to understand WHY that thing should happen that way.

These are two different objectives, and good quality code weaves the two in the appropriate measure.

Having said that, I don't believe all code should be reduced to the subset that a junior dev can understand. Keep it simple when possible, yes. But don't limit yourself, otherwise it's just a shift to verbosity, eating into the finite attention span within the brain. Rather, if the intent is properly documented, then the junior devs can still work on the parts of the code they understand, and reach out to a senior dev when they need to touch the part they don't understand, because even if they don't quite grasp the "how", they can follow the "why" in the code.

Wrong. Machine code is for the computer. Human readable high-level languages were designed specifically for people.
Different newspapers write to different education levels. In your local paper you may find writing that a grade 8 student could understand. In your industry specific journal the writing may be at a grade 12 level.

Not all code should or can be human readable by all.

Right, and some people will work in C, while others will work in Python. That doesn't quite line up with a "grade level", but I agree that different writing styles (or languages) suit different purposes best.

But I assure you, our computers would "think" that we are all idiots for using just about any high level language feature. We write things in loops (computer unrolls it), we give variables readable names so we can think about them (computer assigns it a memory address instead), and we build meaningful abstractions (computer sighs and turns it into meaningless 1s and 0s). So literally all high level languages are written for us feeble-minded HUMANS! Not for computers.

yeah. I've seen a lot of comments like:

    // Sleep for 10 minutes
    sleep(15*60)
Unfortunately, the compiler cannot check your comments. Don't put facts that are better looked up in the actual code and that they only risk getting out of sync with the code.
That's a useless comment. A better one would be:

    // Prevent the two tasks from running right after each other,
    // to reduce load when this is run frequently
    sleep(15*60)
Even the most junior dev can infer that a multiplication by 60 for a sleep function probably means the unit is seconds and we want 15 minutes. No need to spell that out. But why sleep for 15 minutes and not just carry on to the next task? THAT is what the comment is for.
Exactly. Comments are for intent, not what the code does. If I want to know what the code does, I can just read the code.
I've found a better approach to comments is not to put them in at all.

Then, you raise a PR, have a code review, and whatever the other developer is confused about that you had to explain to them - that's where you needed a comment and what you explained to them is what the comment should be.

Developers who have their "head in the code" will almost always (unless they are very smart and very empathetic) fail to realize what is hard for other developers to understand because they will fail to accurately model to context which the other developer has.

And to keep with the theme of self-documenting, the self-documenting version of that would be:

    NAP_LENGTH_MINUTES = 15;
    ...
    sleep(NAP_LENGTH_MINUTES*60);
Still not good enough. Why is this nap function in there? If I want to make it faster and didn't know, I would just remove all references to it. What did I break? Can't tell by that variable name.
a) Self documenting doesn't mean no comments

b) I didn't give enough context for your specific commentary to really make sense. I mean, when did I even say this is a function? It's a snippet of pseudo-code not a code sample.

c) Are you really running around programs ripping out references because you don't know what they do? I'd advise working on your definition of optimization before worrying about whether your code documents itself.

> Besides, code speaks to the compiler/runtime; comments speak to the human. > - The machine need to know HOW something should happen. That's code. > - The human needs to understand WHY that thing should happen that way.

While valuable, some people argue that they should be the same (granted, I mostly deal with high-abstraction language). For example most (all?) lisps have homoiconicity which means the computer and you see the code the same.

Homoiconicity is irrelevant - comment text has no meaning to the computer but can do for the human. Computers have a hard time with "why".
A self-documenting code means we can (relatively) easily see what is being done by the program just by reading the program.

What is one question; why is another. When we work with the existing code (debugging, maintenance) we need to know answers to both questions. So, in addition to a well written (self-documenting) code base we need a document explaining the rationale for the choices that were made and, more generally, the context in which the code was created.

And the other side of the coin is that being too focused on documenting all of your code usually ends up with lots of out of date and confusing documentation over time.
>And the reason that "the code is self-documenting" is a bad smell is because in 3 months even the 'rock star' who wrote it won't remember without appropriate help

That simply means you're working with poor developers.

So you've never written code and come back to it 6 months later said said to yourself, "why did I do this?"
Many years ago yes, but not recently.

If you're a supposed "rock star" senior developer doing this it means you're just a bad developer. If you're a junior doing it just means you have some maturing to do.

There are two kinds of that.

One is "wtf was I thinking", which comments won't help with.

The other is "where did the requirement come from", and that's (1) not a "cock-sure of themselves" sort of thing; and (2) best solved by putting a tracking number on the commit message, rather than traditional code comments.

I think you should rephrase this as "code that can't be explained to a junior developer". There certainly is legitimate code that is not easy to understand without knowing some background.
It's easy to lose yourself as a developer in problem-solving mode instead of looking at the big picture of a project. It's great to have people around you that reminds you the code is just a part of the more complex story - how to help your client solve a business problem.
It's better to lose yourself, IMO. I've been most productive when working with product managers who delivered crystal clear user stories and precisely ordered priorities and took pressure off me having to deal with "that side" of the business.

If I have to deal with ambiguous specifications, vague priorities and to fill in the gaps I need to start modeling the business's needs, operational structure and priorities in order to make appropriate decisions then that means I have fewer cognitive resources to deal with the actual coding.

i.e. it's not just code that needs to be loosely coupled, it's businesses.

That is a hard lesson to learn; I'm still working on it decades in!
Really depends how bright is your "junior developer".

Obviously you cannot expect complex code to be well understood without background and programming capability.

Having well-documented code is one thing, and ability to work on this code without breaking things is another.

Not sure all rules are absolute. If you can write for the lowest common dominator you may not be writing anything overcomplex.
>if you write code that can't be understood by a junior developer

Only true for simple apps (i.e., CRUD, etc.)