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.
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.
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.
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.
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.
>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.
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.
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.
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.
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'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.
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.
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.
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.
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.
"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.
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.
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
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!!
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):
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.
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.
> 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.
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...
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.
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.
> 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.
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.
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.
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.
273 comments
[ 2.8 ms ] story [ 272 ms ] threadFuture me will always appreciate how considerate present me was.
I like this term a lot more than "the next developer."
How can I help you without first helping myself?
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.
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'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.
I realized that when I did that project I "had the time to care" which is not the case lately!
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.
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.
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.
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.
"Fast must be cutting corners and not just actually better at programming" is a weird fallacy to hang your hat on.
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.
hm, something about this that I just can't put my thumb on
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.
Yeah..... pass.
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.
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.
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.
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.
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
Better to have hacky code that delivers value than to deliver nothing.
"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.
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.
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.
But "the map is not the territory"!
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)?
You should expect some additional nuance when receiving a metaphor.
Thinking about code this way takes nothing away from appropriately deep explorations of nuance.
They coexist without issue.
Arguing the metaphor is pointless, because the metaphor isn’t the thing, it’s just a way to explain an aspect of the thing.
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/
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.
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.
> 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
"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
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.
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.
I recently worked on a project with some seriously clean code. My job? Shut it down. This made me sad.
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.
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.
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.
(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.
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.
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."
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.