273 comments

[ 2.8 ms ] story [ 272 ms ] thread
Precisely why I also create READMEs in top-level directories. I'm not going to remember how to structure queries for my API a year from now.

Future me will always appreciate how considerate present me was.

> Future me

I like this term a lot more than "the next developer."

You know how on a plane the flight attendant tells you to make sure your oxygen mask is on before helping others (in case of emergency)? I think of coding well and documentation the same way.

How can I help you without first helping myself?

This is what I tell our junior devs. I remind them that the "next developer" may well be themselves in a year's time.
One can figure out 'how' and 'what' from the code, given enough time. The most valuable thing in code is the brain of the Past Person who wrote it, looming over your shoulder, telling you 'why' in very explicit terms.

That 'why' also helps to show that Past You knew wtf you were doing, and lets Present You feel confident in making changes, because you know what the intent was.

"I'll remember this!" is one of the greatest lies in CS.

Yeah when I find myself wanting to write a comment that describes the implementation, I usually end up writing a test where possible.

I'm trying to think, but I can't come up with any kind of comment that has been useful that didn't have a "because" word, explicitly or implied.

Like, even if there's a comment like:

"This function only queries X and Y fields. Don't add more. If you need more than that, use this_other_function instead."

It has an implied reason behind it, and the mistake is not adding that reason to the comment. So this comment would be missing something like

"[...] because this is being used in a critical part of the code that is very nitpicky and it's very difficult to test because requires some annoying manual steps", or something like that.

There are probably situations where a "what" or "how" comment really are better than "self-documenting code" though. I would probably appreciate those comments if I ever need to read branchless code, SIMD code, or similar performance-sensitve witchcraft.

> I would probably appreciate those comments if I ever need to read branchless code, SIMD code, or similar performance-sensitve witchcraft.

I've done this before in production code. One of my only exceptions to my policy against leaving in commented-out code has been things liking leaving the unoptimized serial code commented out at the top of a section of some hand-vectorized code full of SIMD intrinsic. It clearly showed the intended "what", but was also useful to keep around as a baseline for performance testing and reference code to compare against for debugging.

And remember, the next maintainer could very well be you.
Yeah, it's humbling enough when you are reviewing some old code and thinking "what idiot wrote this" only to git blame and realize it was you. What's even more jarring when you find some code, surprised the capability/feature even exists, then git blame and realize again it was you (this time hopefully with a pat on your own back because of how well it's written). Yes this has happened to me.
All of the code I wrote more than a year or two before the time I look at it strikes me as being embarrassing. I hope this is always true, because I think it says that I have grown as a programmer over that time.
I recently had the opposite experience: encountered some code from 2017(!!!) that was really solid. Few "silly" things but the important stuff was there.

I realized that when I did that project I "had the time to care" which is not the case lately!

Nothing beats the feeling of having a coworker suggest what might be a substantial change to a codebase you haven't touched in months, only for you to look at the code and realize that the way you wrote it makes it a one- or two-line change.
Perfect opening for the classic "well its a good thing I hate myself!" joke.
When I do personal projects for myself, I try to comment them really well for this exact reason.

Just today in fact I was trying to update some code I wrote two years ago because one of the underlying tools broke. I was very happy with past me for commenting the workflow of that tool so I could easily work around it.

A good alternative is code without comments that communicates just as well as that code without the comments. Not necessarily better but less likely to slip out of sync with the comments upon change.
I'm a big fan of self documenting code, but especially when I'm doing quick and dirty projects for myself, where I value speed and cleverness over correctness, the comments really help. Especially when it comes to explaining past me's cleverness.
(comment deleted)
Yes I was only really referencing production long lived code. Mostly I’m a big fan of quick and dirty being something that doesn’t really exist. I believe in quick and throwaway and quick and single/multi use. Comments are fine, just the original suggestion I was referencing sounded like they were a priority.
It's not an alternative, you can't obviate the need for comments with code.

What you're supposed to do is write the code as clearly as possible and then add comments for anything you couldn't manage to express in the code. Usually that'd be all the context around why the code is the way it is and isn't the way it isn't.

I’m just suggesting that the comments are the last resort, the same as you say there. For me, the test names cover the why.
>A good alternative is code without comments that communicates just as well as that code without the comments.

Now this is something I could never do. Or find in other people's code. I much rather appreciate the good comment explaining to me WTF is going on, annotating the larger segments, and so on. Of course it might just be my personal limitation as a programmer that's far from the best in the craft. But to me, comments are the most time tested.

"A good alternative to a car with seat belts is a car without seat belts that is nevertheless equally safe."

There's lots of important information that comments can convey which code itself cannot. In particular, a program's code can tell you how it works but not why it was designed to work that way.

And after a point, even trying to convey too much information about how a program works through code can be cumbersome. We've all seen function names that are way too long, because the author wanted to cram way too much information into it. That extra information should have been put into a comment, where the author could have articulated it clearly, instead of as a single overlong compound verb in camel case.

I write shitty code only I understand for job security. This is probably why I’m a sysadmin lol.
As much as bad code irritates me, I'm not quite so quick to blame the original maintainer - they may well have wanted, badly, to write something better, but been put under artificial (and usually meaningless) time pressure that didn't allow it.
(comment deleted)
I maintain mainframe systems and very often I would like to restructure code to improve it, but the requirement is to make the most minimal change that achieves the fix or change required. Mostly because the code is 30 years of patches and minimal changes which is not well documented and is extremely fragile and not well understood.
So a love letter to myself?

  Who wrote this crap?!
  `git blame` 
  D'oh!
Just today I found an old spec I wrote that was so completely mocked that the code it specified made no difference. I wasn't feeling the love.
Reminds me of the Damian Conway quote "Documentation is a love letter that you write to your future self"
I guess I’m writing hatemail every day.
Sorry next developer, I'm on a tight deadline, used to love this craft, now I just do what the product people tell me to get a nice paycheck.
Yep. Yesterday I ran into a job opening asking for "Java developer who delivers 3x faster than the other developers" in one of the bullet points. It's such a weird point to emphasize that you want speed with no concern to trade-offs, and the maintainability and scalability of the codebase will be the first victims sooner or later.
Sounds like they're looking for a person who'll work 3x faster than the rest of the team by taking shortcuts and slowing everyone else down.
My personal experience is that the majority of developers I ever encounter at work (as opposed to within my social network) are usually slow because they're bad engineers who don't understand problems quickly, don't have the knowledge or experience to see solutions quickly, and in general don't think deeply quickly. It's not hard to 3x performance without sacrifices when the baseline is mediocre at best.

"Fast must be cutting corners and not just actually better at programming" is a weird fallacy to hang your hat on.

There is always a cost to everything.
> There is always a cost to everything.

There's a huge cost to having engineers who are bad at understanding and solving problems. The cost of having people who are good at understanding and solving problems is supposed to be that you pay them more, but that's not how employment incentive structures work in practice because information asymmetry and stigma around talking about salaries.

> the majority of developers I ever encounter at work are usually slow because they're bad engineers

hm, something about this that I just can't put my thumb on

"Majority of people who drown cannot swim."
It's a bit elitist[1]. They're saying we should expect 3x better performance from engineers. We should also expect them to write good code at this pace. The only reason we don't have these things is that most engineers are simply bad engineers. Only people the author perceives as good enough should ever be used as a metric of normal productivity. Presumably the author puts themselves in this group of good engineers.

   1. https://en.wikipedia.org/wiki/Elitism
While this is true, if a job ad is telling me that that's _their_ experience of their average hire, it's probably not somewhere I want to work!
I agree (unless they also pay you three times as much, in which case fair enough).
Especially in CRUD settings when if people would just bother to learn at least a bit about the framework, they could outsource most of the code to that. It’s not like that filtering you have to implement is some brand new discovery that has never been done before.. these apps are literally fancy excel tables very often.
I used to work with this kind of developer. He was bounds and leaps faster than all the other developers in the team.

The code he produced was absolutely and completely unmaintainable. The joke was that this guy could program C in any language. His code kindof-sort-of worked, but only he understood it and when anyone else had to take over his stuff, the first thing they had to do was rewriting the part from scratch. Of course there were no tests, so when the new person broke something in their attempt to try to work with their code they were scolded. The person in question was the CTO of the company, by the way.

He was 3x alright, but at the expense of everyone else on the team. I was very glad to see him go.

"You'll get to work on a codebase for whom the entire development mindset has been 3x-speed-at-all-costs."

Yeah..... pass.

There are cases where the tradeoffs don't involve the actual codebase. For instance, there are certainly many developers who are 3x faster than the average developer simply as the result of having enough experience and/or skill to know which tools and/or approaches are optimal for a large subset of the kinds of problems they encounter in their typical work, such as a developer familiar with a particular ecosystem accomplishing some task in 10 minutes by knowing which library and which function to use, and how, whereas another might take hours (or days) to accomplish the same task since they have to figure out what tools are even available to solve an issue and how to use them, or worse (sometimes), rolling their own solution where a library implementing the functionality already exists. The tradeoff here is simply that it will be harder to find such developers, and they'll generally want higher compensation, but their work will not degrade the quality of the codebase, quite the opposite.
I like those offers, they self-identify as places to avoid
The craft is not the code, but the product.

You can have beautiful code and garbage product, and great code and a garbage product.

If your PM is pushing bad products, that's on them. Your job is to deliver good product, not good code.

Can’t it be both?
It absolutely can!

I'm not saying that you should disregard your code, just that it's not what you should put at the top of your list.

You can build amazing products with amazing code, and they will often raise each other up.

A great example is Redis, that codebase taught me how to write C code, and I also use Redis everywhere.

That’s not a great way to look at it. You can be passionate about the craft and not passionate about the product. You can usually find interesting problems relating to craftsmanship even when doing things you’re not thrilled to do.

Let’s be honest: sometimes you’re not “changing the world” like many founders like to think, just building yet another shopping cart.

If you lose love for your craft there’s no product that’ll cure it.

Well said. I am certainly not in this game because I love building forms. Mastering my tools of choice grants me satisfaction. It's hard to find a place working on a product that is truly interesting, but fortunately at least, finding a place working with tools I like is easier.
But you're trying to build a damn good shopping cart, which is the product.

The code analogy here would be nerding out on how to use a hammer in spectacular ways, but not really do anything interesting with it.

You can still really love your tools, but you shouldn't focus on them as much as what you're building with them.

> The craft is not the code, but the product.

These two are not disjoint, but instead quite related.

> Your job is to deliver good product, not good code.

If your job is software engineering, then "good code" is what facilitates "good product." It boils down to maximizing the "abilities":

- Understandability

- Applicability

- Testability

- Maintainability

- Flexibility

- Durability

Yup, good code helps to deliver a good product, but you should not focus on the code, rather focus on how the code influences the product.

Better to have hacky code that delivers value than to deliver nothing.

This is a false dichotomy IMHO.

"Hacky code" is most often a result of those responsible for delivery having gaps in their understanding of the product need.

When engineers have a deep understanding of what is needed, there is rarely a need for hacks. Of course, the obvious exception to this is when libraries and/or external services mandate them.

It's true that the product should take priority over the code, but there's a limit to by how much. If the code is bad enough, its low performance, bugginess, and slow feature development will eventually be reflected in the product.
Performance and bugs are product features, not code features.

Who cares if it slows down feature development if you never have to change it. If it does impact the product, it then becomes part of the product value you're delivering. This is the time you should be investing in better code.

Sorry future me, I'm on a tight deadline. If I spent an extra two hours making this better now, you wouldn't have to spend two days fixing these problems. You're probably still on a tight deadline.
"I love deadlines. I love the whooshing noise they make as they go by." -- Douglas Adams
In my opinion, good code is like a Brita filter. It does its job, will one day need to be replaced, and it should be easy to replace.

More importantly: metaphors are not a healthy way to understand an idea. Ideas are more nuanced than a metaphor could possibly account for. Abstaining from metaphors might not make for a catchy headline though.

Little pushback here - metaphors are great tool to understand something, and can convey some meaning more efficiently than other means.

But "the map is not the territory"!

The territory isn't the territory either, so no big deal!
Metaphors are also ways of communicating ideas. A good metaphor is as simple or as complicated as it needs to be in illustrating a new concept
Problems arise as soon as you (ab)use a metaphor (used to explain a higher level/adjacent problem) to explain concepts it was never meant to model.

Example: Array of items as a shopping cart: how do you efficiently remove an item from the array (as you can from a shopping cart)?

(comment deleted)
There's always a possibility that a bad metaphor can be made, but this doesn't mean that metaphors themselves are bad. They require at least some consideration in order to communicate and relate the relevant details of something to another thing. It would be like criticizing multiplication because sometimes people forget to carry extra values
metaphors are like, herding .. fine old .. elephants .. in the air
In my opinion, metaphors are like a picture. They can communicate vast amounts of information very quickly but can have inaccuracies.

You should expect some additional nuance when receiving a metaphor.

Is this supposed to be ironic? Your first sentence was a metaphor.
Why can’t good code be all of the above?

Thinking about code this way takes nothing away from appropriately deep explorations of nuance.

They coexist without issue.

The headline is a simile.
I think the issue you may have with metaphors is that people tend to argue the metaphor rather than engage with the concept.

Arguing the metaphor is pointless, because the metaphor isn’t the thing, it’s just a way to explain an aspect of the thing.

good code is like vintage wine: you don’t recognise the packaging, no-one agrees on how exactly to describe why it’s good, and the only person who still remembers all the details of production retired ten years ago
Metaphors are a fine way to understand an idea if one accepts that their purpose is to leverage an existing understanding of something, and that they're lossy. So I guess my issue with your comment's second half is that I don't think metaphors are being used as a shortcut to a full and complete understanding of a topic. They're an aid and I think that is mostly how they're used, IME. I don't think they should be written off.
Unrelated, but lately I find that I have a much harder time learning with metaphors than if educators and explainers would just speak directly about things. I had very terrible experiences learning physics because teachers would always resort to weird metaphors, about music, about electricity being like a river, and more.
fuck the guy after me. I write good code for my own sanity and so my OCD doesn't make me want to refactor it all later. it's like saying save the trees for your grandchildren or the future generations. fuck them, I want a clean environment for myself gosh darn it!!
The next developer ruins your code like new twitter runs old twitter or new arrogant engineer overwrites old humble engineering.
1) "Code sober, debug drunk"

It's harder to read the code than to write it so if you can barely comprehend the thing you just wrote, you probably won't understand it in the future: https://sonnet.io/posts/code-sober-debug-drunk/

2) I think it's more like speaking with ghosts (including a spoiler for The Sixth Sense):

https://sonnet.io/posts/emotive-conjugation/

>it’s harder to read code that to write it

Isn’t this only true of bad code? Good code is almost certainly the other way round, harder to write than read… just like a really good book was much harder for the author than it was for you, the reader.

Code isn't a book.

The quote you call into question is semi-famous and I believe the idea is that it's relatively difficult to jump into one code unit of a larger system and get back up-to-speed because one must fill the data cache of their brain with all the considerations for why the author may have done things in a certain way. The algorithm choices and edge cases and exceptional logic paths were clearer to the one writing the original at the time.

I agree with the sibling comment.

> just like a really good book was much harder for the author than it was for you, the reader.

Now, I suppose this could work for a nested narrative novel, where the reader is meant not to just read the book, but to rewrite and expand it as they're reading it. Adding new ideas, new sub stories on the way. Think 100 Years of Solitude blended with Italo Calvino's Invisible Cities.

Seems like the [*]Bible is a good literary example of an async collaboration similar to code: notoriously hard to interpret, and full of dubious historical information and contradictions.

I know that Christians call it the "good book", but most of them don't use the word "good" in the same way they'd use it to describe a Nabokov or Eco novel.

[*] or most ancient religious texts, like Avesta

Plot twist: that next developer is you. Love yourself!
I prefer the quote that goes

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."

This. I was about to mention the same quote. This quote alone has served me well over the years. Sounds jokey but if you live by this, it’s brilliant.
This blog entry is a much nicer and more graceful version of the old adage about writing your code like the next guy is a psychopath who knows where you live...
Most bad code doesn't exist because the writer didn't sufficiently love the future maintainers.
Good infrastructure is too. I had a colleague deploy the power whip for the last available rack position on his way out the door.

Years later when I desperately needed that rack to keep the site up I was able to roll it in and light it up without waiting 6weeks for an electrician change request.

He saved my bacon by thinking ahead. It was a gift he gave me, never mentioned and was not around to receive thanks for.

I aspire to be more like him in everything I do.

Good code is not like art, such as good books or paintings. No matter the quality of your code, if the product or service is not a good market fit. It will be retired. No one will stumble upon it or pick it up after it's gone. Knowing this, the only reason for putting effort into it is to make it easier for myself.
The two aren’t always mutually exclusive, you might be writing code for a good market fit that stands the test of time and needs maintaining.

The times you appreciate it are actually when you open something and it’s nice and easy to change and you realise you were the one who wrote it. But real developer happiness comes when you have the same experience and someone else wrote it.

Indeed, I'm just trying to highlight your efforts as an 'artist' might be wasted.

I recently worked on a project with some seriously clean code. My job? Shut it down. This made me sad.

> No matter the quality of your code, if the product or service is not a good market fit. It will be retired. No one will stumble upon it or pick it up after it's gone.

This applies to artistic endevours like books and paintings as well (especially those two, since markets for them are very oversaturated). Your technique might be masterful, but if your art doesn't align with current trends (along with a number of other factors), it'll drown in the endless barrage of other art, and nobody will stumble upon it or pick it up, even if it's still available.

Yes I thought about that, I was thinking in the sense that someone in the future might actually stumble upon a painting or a book. They won't with proprietary forgotten code.
> The beauty of our creations, however, is not judged solely by the elegance of our algorithms or the efficiency of our code, but by the joy and ease with which others can build upon our work.

Often this is not true. Our creations are judged by the user. They don't care how good it is under the hood. They care that it works correctly, that it's easy to use and that it's as fast as they need it to be.

Your boss should care that it's well written because that should mean it's cheaper to maintain. But, they don't look that far into the future when evaluating your performance. So, often they only care about how fast you did it and how happy the customer is with it.

Our industries incentives don't often align with good code.

"Roses are #ff0000, violets are #0000ff, ..."
The computer in this metaphor is what, a marital aid?
dear future developer, nothing matters and code will still be hard to read even if I try my very hardest to make it as good as i can. the world is dying and we are doing our best to kill it. you having a hard time understanding my code is not really anything that can be fixed. it pales in comparison with the actual problems the world faces. tough it out or rewrite it. sorry
Meh. I've seen teams and projects bogged down by "good clean code" rules and nit picking code reviewers. These folks, typically "staff" engineers, over-police the repos and care more about clean code than delivery and execution.

I'm waiting for the day where AI/co-pilots can enforce team and industry best-practices, style, maintainability, testability, etc before the code is even committed.

Call it "uber-linting" and get rid of code reviews.

Can't you already do that with pre-commit hooks? We use those at work to check a lot of stuff like that before a commit ever goes through.
Of course! I'm talking about the kinds of checks and scans that are made on the code during the pre-commit hook
I'm working with someone who asks me to remove documentation that summarizes what a function does.

(The whole codebase is stripped bare of documentation.)

Copilot can write implementations based on comments. Soon I think it could flag potential errors if code doesn't do what the comment claims it does. Then we can do that in code checks.

This mentality drives me crazy. I mean i agree that most comments are bad, but some high level description what a function/object/library does or how it is supposed to be used is something different.

When it misses then I have to read the ** code to use the ** thing. And I am not interesed in that at all. Maybe they do this so someone has to read their "good" code.

It's a very nice way to imagine good code. More likely, someone inexperienced or less caring will come along and edit it just enough to turn it into mediocre code and no one will care anymore.
Truth.

Years ago a wise man told me "The compiler is not your customer. The next person who maintains this code is your customer. It might be you."

The customer is the one using your product, not the one maintaining your code.
A common reply, but misguided. A corporate coder who is not also CMO and CEO does not produce products for the end user. They produce code units which, after build, deploy, and integration, become useful building blocks in an overall solution which may (the company hopes) be a product for the end user. From this standpoint, the code they write will often be 'consumed' by other coders and by future themselves. The consumers are therefore coders.
Sure, but usually you develop an interface to your service/code, and they shouldn't have to know the internals.

If they have to look at your code to figure out how to use it, you've already lost. Hence the code isn't the product, it's the means.