Readit News logoReadit News
aaronbrethorst · 2 years ago
This feels borderline tautological: good code is good because it’s good.

Good or bad, you’re going to end up needing to add new features to this code. Or someone misunderstood an input or output to/from this code and you’ll need to read through it to understand how it’s implicated in a bug.

I think ‘good code is easy to read’ is pretty profound: DRY code with the right abstraction is easy to read. DRY code with the wrong abstraction is hard to read.

bayindirh · 2 years ago
Have you ever had the need to read the source code of a tool because it doesn't behave the way it should, and its help and documentation prescribes?

I have been there a couple of times, and how some stuff is handled in these codebases were sad. Sloppy, assumption ridden, or pure, inelegant and fragile hacks.

Even if you're reading a code to modify it, good code is easier to follow and read (point of the junior developer), and as a result, you touch less and less parts of the code to develop it even further.

So yes, Good code is rarely read, or "read less, and in more niche cases".

gravypod · 2 years ago
> Have you ever had the need to read the source code of a tool because it doesn't behave the way it should, and its help and documentation prescribes?

I believe this varies wildly programmer to programmer. I'm often diving into code and reading that when debugging. I've done this with many code bases. It may be debatable if any of them are "good".

chaboud · 2 years ago
There’s a thin sliver of things I have read through that I considered good (even great) that were high effort to read. Things like STL, boost (in parts), numpy… huh. Come to think of it, all things that use C++ templates… and I’m a big fan of templates…

The thing they all have in common is that they are/were overwhelmingly useful to people who didn’t need to go digging inside of them to use or understand them. These are bodies of code for which the behavioral and algorithmic properties were documented thoroughly, bodies of code that generalize to wide ranges of applications.

Still, we’re not all writing STL core classes every day. Sure. Write code so good it doesn’t need to be read. Write code so good that people want to read it. And write code that, when read, is welcoming, comprehensible, and considerate of others or yourself in the future.

Saying the first thing shouldn’t mean unsaying the other things… Something our author may learn over time.

aaronbrethorst · 2 years ago
I would argue that lots of useful code is an utter dumpster fire internally. That doesn't mean we shouldn't strive to do better.

        Useful
          |
          |
    Bad-------Good
          |
          |
      Not Useful

ModernMech · 2 years ago
It's because they are using "read" to mean "understood/interpreted" in the sense that the reader is executing the program in their head.

In their last paragraph:

  It should be so well-structured and named that its purpose and functionality are immediately apparent [when read]. This minimizes the need for others to read through **and interpret** the code, allowing them to use it more effectively.
(emphasis added)

So the point is really: "Good code should be so apparent that when the reader reads it they do not have to be a human interpreter."

Sakos · 2 years ago
Is that possible? I'm not sure if I've ever read code like that before, but maybe that's just me.
petermcneeley · 2 years ago
I think you are not reasoning correctly here

Adding features to a code means it was incomplete. Misunderstanding input/output usually means it is poorly documented or lacked a good API. A good API works at the surface (in/out) and not in the volume.

Really good code solves a problem completely. I have worked with such code and yes almost nobody ever goes into this code (and makes changes).

wavemode · 2 years ago
> Adding features to a code means it was incomplete

In practice this isn't true. The code may have been perfect and complete according to the business requirements of 1 month ago. But the business requirements of 1 month ago and today are often completely different.

x0x0 · 2 years ago
> Adding features to a code means it was incomplete.

That definitely implies code can't be good if needs change, which makes no sense to me.

cjblomqvist · 2 years ago
I thought you extended, not edit, really good code to achieve that
nsinreal · 2 years ago
Well, what's wrong with code being incomplete at some point of time?

Is it not waterfall enough? Is it too much learning from customers? Is it too small PRs of duration less than 1-6 months? Is it not enough premature optimization?

aaronbrethorst · 2 years ago
Let me guess, you work on game engines?

Dead Comment

pydry · 2 years ago
Most essays about good code seem to end up being tautological.

The good ones dont.

Dead Comment

Dead Comment

strnisa · 2 years ago
In the real world, code is read often and for many reasons. The main ones I can think of are:

    1) To understand the system without necessarily wanting to change anything. This is common with new employees or anyone wanting to learn more.
    2) The system often needs tweaks, bug fixes or new features. Each of these normally requires that the code in question is read by several people several times.
    3) The architecture is normally not perfectly modular, so changing one part often requires one to understand and tweak the neighbouring parts of the system, too.

jongjong · 2 years ago
I agree with the first one but the other 2 are basically what the author is speaking out against.

Some change/rework is unavoidable, but if code is good, then it should be relatively rare. Modularity isn't sufficient for code to be good. It's difficult to have truly 'loose coupling' without 'high cohesion'; each module should have distinct and well-defined responsibilities. My test for high cohesion is the question: "Is this module easy to describe to a user with limited technical abilities?"

If modules are both loosely coupled and high cohesion, you'll find that you rarely need to change the code, or won't need to change it much, even after substantial refactorings. This is because such modules provide a near-optimal level of abstraction. Interfaces of such modules tend to be simple (a relatively small number of simple parameters, e.g. primitive types); this is what makes the modules easy to substitute.

For example, consider a database client library, the most powerful method is for running queries against the database; this method typically requires only a single argument as a query; a string, though it will also typically support an object/map as second argument to substitute values into the query. How often do you need to change the database client library because of a refactoring? You could literally pivot your entire business model from a social media app to an enterprise CRM and you wouldn't have to change a single line of code in your database client. You might change how you use your database client within your back end logic, but you won't have to change the implementation of the client itself.

There are many less extreme examples though where a module can handle very significant changes to your business without having to be modified at all. Maybe your business pivoted from being a professional/business social media app to being focused on friends and family; it might change some aspects like friend discovery, algorithm recommendations, banning, etc... But you should be able to keep most of your existing code if your code is good quality.

My definition of good code is "Code that is resistant to change when faced with requirement changes." Though there is a lot of overlap with "Code that is rarely read."

nsinreal · 2 years ago
That's kinda unrealistic. It's okay to expect that if you change the requirements for A, there should be no changes in the code of B. It's not okay to expect that if you change the requirements for B, then there should be no changes in the code of B.
davydm · 2 years ago
I don't think the author has worked on long-lived projects. Eventually, all code is revisited because there's always shit to get done.
madsbuch · 2 years ago
Exactly my thoughts.

The reason why good code is code that is easy to read, is because products evolve, and so does the code.

Suddenly the taxonomy of that enum starts to shift, and the name that was perfect yesterday does not make sense tomorrow.

These changes happen gradually and a basic acceptance of the code base not being on par with the product understanding is necessary in order to have any kind of velocity on not only spend time refactoring.

m463 · 2 years ago
I disagree.

"good code is easy to read" - that does not work.

I can write a bubble sort instead of quicksort and that code will be bad.

Maybe you can do the same thing with privacy policies. Most complicated privacy policies are bad, so they make them hard to read so that people do NOT understand them and give up.

But you could have a privacy policy that is bad and easy to read. "We can do anything".

I think good code is primarily easy to read. And I think it should not attract attention through bad behavior, so it should additionally not come under scrutiny for that.

weebull · 2 years ago
There's a class of code where you never need to read it because it's effect is well understood and it does it without problems. It has the right level of abstraction to be useful in multiple places and not specific to a singular case. It's not going to be top level code, but it's a building block you know you can rely on.

This is something I think functional styles of programming lead more naturally towards than OO or procedural. It's far easier to separate concerns when you can pass around like bundles of functionality (i e. first order functions). Also it really helps when you are used to writing code with no dependency except what is passed in, and not effect except what is returned. Then thhen you're sure that the code is not leaky in it's abstraction.

You can do it in other paradigms, but it's it's not where the language naturally leads you. OO has retained state as a key foundation of it's philosophy. Procedural code tends to mix up the how something is done and the what is being done. (e.g. the iteration through a data structure, with the definition of what is being searched for).

Deleted Comment

wglb · 2 years ago
I did a consulting gig at Allstate around the time of Y2K. I chatted with a senior architect who had been with the company for over 20 years. He noted that there were such a vast array of programs and systems in place, some of which had been running for at least 40 years. I wonder if any of that code had been read, good or bad, for decades. And I am willing to bet that the source code for some of it was lost.

This of course led to no small level of anxiety during the run up to Y2K.

As a side note, while I was there, the dictum came down that there was to be no more assembler programming to be done.

I know what you are thinking. They should just burn the mainframe with fire and rewrite it all. I recommend the book https://www.amazon.com/Kill-Fire-Manage-Computer-Systems/dp/....

chaboud · 2 years ago
I had a similar reaction while reading this, something along the lines of “well, that’s a bunch of idealistic tripe”.

And, honestly, I think that somewhat holds. That said, as an aim, writing readable code that doesn’t need to be read to be used is a good one.

I wrote as much in a quora response almost a decade ago to the question “how does one become a great coder” ( https://www.quora.com/How-does-one-become-a-great-coder-prog... ), and I think it still holds.

However, the other part of that answer was to make the code immensely readable, because we read more code than we write unless we’re incredibly junior or comically superhuman.

bena · 2 years ago
Not just long-lived projects. Working on bespoke, internal systems means you’re never truly done. And what you’ve done a month ago may not be what’s wanted now.
drewcoo · 2 years ago
The long-lived projects I've seen have some code that mostly works that doesn't have any tests and is hard to grok. Nobody touches it because 1) any change might break something unexpected and 2) if you touch it, you might end up owning it.

I wouldn't call that good code but it's often too good to spend time replacing.

jeremywho · 2 years ago
I don’t think you read the whole article. I had the same thought as you from the headline, but they gone on to state that good code is so easy to read when you need to make changes that you don’t have to go through it multiple times to make the required changes.
rodelrod · 2 years ago
This is only (theoretically) true in the sense that if you build the perfect abstraction, you should not have to think too often about it.

Building good abstractions requires: 1. skill that is in relative terms rare in the profession; 2. enough experience with the problem domain that the abstraction provides the perfect balance between ease-of-use and flexibility as the context changes; 3. a dedicated individual or a small team who nurtures and gatekeeps the evolution of the abstraction obsessively.

For the other 99% of real world cases, the best you can do is try your best to build decent, not-too-leaky abstractions for the problem as you face it today, and the underlying code better be readable because you'll need to maintain it constantly, as will all kinds of other people in varying states of cluelessness.

SatvikBeri · 2 years ago
Recently I was going through the codebase that our company has spent the last 7 years developing, trying to find examples of code we reuse a lot. This turned out to be very unintuitive: the functions we actually reused the most had practically fallen below the threshold of conscious thought. They almost "just work", so I hadn't realized how much I'd been using them.
rmah · 2 years ago
Those who are disagreeing with the author seem to not realize that he's just engaging in a bit of navel-gazing wordplay. Sort of like when people say "good programmers should be lazy". What they really mean is that good programmers should think ahead and craft their code with an eye minimizing future modifications.

Similarly, I think the author is simply saying that well written, easy to read, easy to understand code shouldn't have to be re-read multiple times by the same person. Which is good. The inverse would be that difficult to understand code would have to be read, re-read and studied deeply to actually grok. And thus read a lot. Which is bad.

madsbuch · 2 years ago
I think the critics (myself included) perfectly understood that point.

> What they really mean is that good programmers should think ahead and craft their code with an eye minimizing future modifications.

The critique is exactly that this can not happen in real world projects because you can only speculate what requirements for the code base is down the road.

To counter this I usually apply two princinples:

1. Occam's razor - implement the simplest solution

2. Write code that is readable and understandable, so it is easier to change the code with the requirements.

The last being completely opposite to what the author of the article thinks.

The worst thing I can think of is somebody needlessly DRYing up a code base prematurely - this is in my opinion a junior behavior.

rodelrod · 2 years ago
Basically he's saying that if the API is great you rarely need to read the implementation. To which: sure, in some blessed cases where the API was great to start with and nothing changed so you don't need to change the API or the implementation.
AtlasBarfed · 2 years ago
It is not good to use the word good for serious discussion of any topic.

It's morning, and I really hope I did successfully pull off something close to real irony there.

karmakurtisaani · 2 years ago
Something almost like straight out of a Garth Marenghi novel. Now go have that coffee.
m463 · 2 years ago
also, nobody should be investigating the code because of poor behavior, say a bug or poor performance of some sort.
CodeMage · 2 years ago
The corollary of the author's argument would be that no C++ code is good ;)
sgbeal · 2 years ago
> In conclusion, good code is rarely read.

i offer the entirety of sqlite as a counter-example. Based on that project's forum traffic and my participation within that project, i estimate that there are hundreds, if not thousands, of people who actively read that project's C code. That doesn't make it "bad code," that just makes it code which people want to understand (which, in turn, requires reading).

drewcoo · 2 years ago
The assertion was "good code is rarely read."

    good code ⇒ rarely read
In that context, "often-read code" does not tell us anything about code quality. And often-read code that's not bad is not a defeater.

mekoka · 2 years ago
On the contrary.

A = "good code"; B = "rarely read"; C = "often read"

A implies B

B is exclusive with C

X leading to C implies X is not A

protomolecule · 2 years ago
But is it good?
jacksnipe · 2 years ago
It's generally held up as the standard codebase that you can go read to learn how to write "good C", so community consensus appears to be yes.
WillAdams · 2 years ago
There is an entire discipline on the idea that the effort to make code easily read/understood will result in source code which is easier to maintain and write:

https://literateprogramming.com/

(or if that's off-line, see: https://en.wikipedia.org/wiki/Literate_programming )

and published books which exist so that folks can read the source code of programs:

https://www.goodreads.com/review/list/21394355-william-adams...

lelandfe · 2 years ago