programming is terrible
programmingisterrible.com · Personal blog · on HN since 2013
Personal blog on software engineering practice, architecture, and the web, covering code design, monoliths, REST, and programming folklore.
What HN saysHN commenters repeatedly cite 'Write code that is easy to delete, not easy to extend' as a classic and want more posts like it; its follow-up on debugging also gets linked.
124HN people shared it
49linked it in comments
100stories submitted
3.1Kstory points
5 months agolast shared
2013people per year2026
Most-shared posts
- 1Write code that is easy to delete, not easy to extend27 people · 1.2K points · first shared 2016 · 133 comments on HN
- 2How do you cut a monolith in half?13 people · 268 points · first shared 2017 · 59 comments on HN
- 3The Devil's Dictionary of Programming9 people · 134 points · first shared 2013 · 8 comments on HN
- 4Repeat yourself, do more than one thing, and rewrite everything9 people · 18 points · first shared 2018 · discussion on HN
- 5How to Parse Ruby8 people · 135 points · first shared 2013 · 84 comments on HN
- 6Write code that’s easy to delete, and easy to debug too6 people · 43 points · first shared 2018 · 1 comments on HN
- 7What the hell is REST, Anyway? (2019)6 people · 6 points · first shared 2019 · discussion on HN
- 8Programming is Terrible5 people · 171 points · first shared 2013 · 68 comments on HN
- 9Scaling in the presence of errors–don’t ignore them5 people · 16 points · first shared 2019 · 1 comments on HN
- 10Why did Dijkstra Hate Basic?5 people · 2 points · first shared 2013 · discussion on HN
- 11Postel’s Principle is a Bad Idea3 people · 147 points · first shared 2013 · 60 comments on HN
- 12Write code that is easy to delete, not easy to extend (2016)3 people · 74 points · first shared 2020 · 30 comments on HN
- 13Come here and work on hard problems – except the ones on our doorstep2 people · 344 points · first shared 2013 · 370 comments on HN
- 14How to Befriend Crows2 people · 22 points · first shared 2021 · 4 comments on HN
- 15Why your distributed social network will not work2 people · 13 points · first shared 2013 · 7 comments on HN
What HN people wrote when they linked it
swah · 2023-12-22
https://programmingisterrible.com/post/139222674273/write-code-that-is… is the kind of stuff I'd love to have one per day
Benjammer · 2022-05-22
Reminds me of this classic: https://programmingisterrible.com/post/139222674273/how-to-write-dispo…
amai · 2020-07-22
The author has a followup:
"Write code that’s easy to delete, and easy to debug too."
https://programmingisterrible.com/post/173883533613/code-to-debug
rlonn · 2020-06-08
This is the usual response from engineers who love their work :) In my experience there is always a point to NOT doing things "well" the first time round. Read the old article on "programming is terrible": write code that is easy to delete, not easy to extend: https://programmingisterrible.com/post/139222674273/write-code-that-is…
williamallthing · 2019-09-14
Because every system that needs to return a response within N ms (which is pretty much every app, service, API call, etc) ends up being implemented with synchronous calls, with messaging only used for truly offline bits. There's a good writeup of why here: https://programmingisterrible.com/post/162346490883/how-do-you-cut-a-m… , with this great quote: "In practice, a message broker is a service that transforms network errors and machine failures into filled disks".
(I used to work at Twitter, which went through this same transformation, but if you watch tech talks from pretty much any other modern company that it building a big distributed system, you'll see the same pattern.)
lettersdigits · 2017-02-19
> The best code is the code that is easiest to manipulate and modify
this great (IMO) article comes to mind:
http://programmingisterrible.com/post/139222674273/write-code-that-is-… :
"Write code that is easy to delete, not easy to extend"
akkartik · 2016-02-28
> which is an abuse of DRY because it should only apply to concepts, not code
As a 'copyista', I would change this to "DRY should only apply to production code, not tests." It wasn't clear from your reply if you agree or disagree.
A couple of great recent links about this IMO under-discussed topic:
http://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction
http://programmingisterrible.com/post/139222674273/write-code-that-is-…
http://bravenewgeek.com/abstraction-considered-harmful
AndrewDucker · 2015-03-15
If you liked this, then you'll like the associated blog:
http://programmingisterrible.com/
Mawr · 2023-07-20
> I'm not sure why you think that quoting random HN users proves anything except personal opinions of specific people? These are fine, but other people have other opinions.
They support my argument so I included them. I don't see a practical difference between a "random HN user" and a random blog post or anything else. A good idea is a good idea, regardless of the medium.
> I don't oppose the "principles" you've quoted, but they would just as easily apply to e.g. Haskell
Possibly, I threw it together pretty quickly, so it's not very thought-out.
> (maybe except for the "there's only one way to do it" which however has never been true of any language, including Python).
It's not binary, but a spectrum. No language has just literally one way to express each concept. However, Python is definitely further towards the "one way to do it" end of the scale. Perhaps not as much these days as it used to, but still far more than for example Ruby or Perl.
> I feel like you missed my larger point. It's not terribly difficult to write code that you can understand line by line. It's incredibly hard to write a huge code base in a way that you can reason about many code paths simultaneously, however. That's where the abstractions start to make sense.
I thought I adressed that; everything I mentioned - explicit error returns, pure functions, no global state, and no metaprogramming - all show their true worth in large and/or unfamiliar codebases.
> I don't understand why people think…
whoopdedo · 2022-01-13
Sounds like a restatement of Postel's robustness principle[1]. Did it go out of style to "be conservative in what you send, be liberal in what you accept" and we need to relearn it again?
Well, perhaps it did. History has shown the dangers of not handling malformed input well. Postel's principle has received scrutiny[2] for reinforcing those mistakes by creating a mistaken belief in robustness. More recent recommendations have been to be stricter in handling of inputs[3].
But I think there is some confusion between robustness and defensiveness. "Be liberal in what you accept" may be confused with "don't sanitize your inputs" when not sanitizing is the less liberal action. Robustness means the program should not fail if it receives input it didn't expect. A program that crashes, hangs, executes unintended shell code, mangles the data, changes the thermostat, or other undefined behavior is not being robust. To prevent that from happening then data must be sanitized at input so that it can be processed without those side-effects. The examples of programs failing robustness have been because they were insufficiently defensive.
The bigger issue is that robustness doesn't scale easily. You may know how your bit of code will deal with malformed data, but what about every other library you use? Or other systems you communicate with? It becomes a backstage problem, where once someone has gained access to a restricted area it's assumed they are authorized to be there. The further…
allan_s · 2019-03-18
I would like to point out a possible problem with the generic advice "read books" "follow blogs etc."
=> technological bias
As you are from Node/Express and Mongodb background the biggest risk is trying to become only better in these technologies. So you will only know how to make faster horses, how to train them for the best, but you will never learn car exists.
More than best practices, what makes a great developer valuable (especially in a position like you where other people in your company are less experienced than you) is your ability to see wider not deeper.
Try to challenge the status quo ? Why MongoDB? What kind of alternative do you have ? Same for Node + Express.
Doing so will force you to see where your tool shine and where it reach its limit. Doing so will permit you to know when you need to dig deeper on "how to use better this tool", and when to step back and "wait a minute, no amount of best-practices/knowledge will balance the fact that MongoDB is just no the right tool here"
So read a lot, but also from people that are not from your community (and to be honest HN is a good starter on getting different point of view)
The other important things is about perspective, it's not because a googler/guy from netflix wrote about how they needed to split the code in microservices, or needed to implement $design-pattern-with-a-very-cool-name that it does apply to you.
Especially looking to the size of your dev team, I think the worst things that could happen to…
dexwiz · 2018-12-30
I really agree with the quote, especially after spending some time in a huge enterprise codebase (1mil+ files). Writing reusable code usually means writing an abstraction layer. However, if you always write an abstraction layer, you will end up with a ton of abstract code with only one concrete implementation. Abstract code is harder to read and modify, so you do pay a cost when it comes to maintenance. Also depending on the language you may pay a runtime cost also. So if your goal is always to write reusable code from the start, you pay an investment cost that may never show any returns.
This idea pairs well with another Knuth quote regarding premature optimization being being evil [1]. Code reusability is a form of optimization of developer time. Writing reusable code with only one implementation is like optimizing a function that does not impact performance. You think you are doing something good because programmer dogma says its good, but in the end its not.
Here is another related article that does a great job talking about maintainable software, and some of the contradictory advice you will hear about it [2]. But the main point is that code is transient. We tend to write code with the idea that it may run in production undisturbed for decades, but that is not the case. Refactors are common, and most people will do a better job rewriting code from scratch than trying to modify your code. So do them a favor, and make it easily replaceable instead of easily modifiable,…
jerf · 2018-09-17
Assuming you mean in the computer realm, write code. Make it do things. Figure out how to debug it. Have fun.
I'm not being sarcastic. There's no particular point in trying to pick up particular skills. The specifics you pick aren't going to be marketable no matter what; what matters is the general skills you pick up and how quickly you can leverage them to learn later.
I'd recommend avoiding hyperspecialization; it's kinda easy for a 13-year-old to become something like a master expert with RPG Maker or something, but unless that's your end goal, that can kinda be a bit of a trap. (You end up with an understanding of computing too bent around local considerations and get too much time into learning hacks around them, and mistaking them for fundamentals. When Dijkstra was complaining about BASIC [1] this is the sort of thing he meant. If you spent too much time learning how to deal with the limitations of 1970s/1980s BASIC you came away with some really bent ideas of how to do good programming.)
Oh, and try to avoid putting any sort of dynamic website up on the internet if you can avoid it. Web security has gotten quite hard. If you want to build a website I recommend static site generators; you learn a lot of good stuff applicable to web development, but security is a near non-issue.
(And for the love of all you consider holy, stay away from cryptocurrency.)
[1]: https://programmingisterrible.com/post/40132515169/dijkstra-basic
melloclello · 2017-06-04
> It’s no secret that I really like Clojure and as a lisp, it was the easiest language for me to start the prototype with, but there’s no reason this couldn’t be done for any language with a dynamic runtime. The rest is mostly simple analysis of an AST and some clever inference.
I have looked into this. It is kind of criminal that for most real world languages (Ruby[1], C[2] etc), it's not possible to just define a grammar and throw it at a standard parser generator for them - they generally have one or two quirks which make this infeasible.
In my ideal alternate universe it would be considered unthinkable to publish a language without also publishing a grammar in a standard format for said language, which can then be plugged into your favourite text/semantic/tree editor. Our tools should dictate our languages, not the other way around.
[1] http://programmingisterrible.com/post/42432568185/how-to-parse-ruby
[2] https://en.wikipedia.org/wiki/The_lexer_hack
vanderZwan · 2016-03-05
Reminds me of an article about the Scratch programming language, where the author noted that being based around visual drag-and-drop blocks instead of text strings meant it was trivial to translate any Scratch program on the fly:
> Scratch, albeit visual, is still a language built around sentence fragments. Instead of using punctuation and assorted ascii art to enchant text into code, the structure and action of a Scratch program is almost as clear as prose. By using natural language fragments instead of magic identifiers in text, Scratch is unique in another aspect — Internationalization — Scratch programs can be built up out of German, French, Chinese, Japanese fragments too.
> The look on peoples faces when you change scratch into their native language is worth treasuring, an aha moment where the code becomes readable in an instant. Scratch is so readable that it has come as a surprise to some, one remarking “I understand this. It can’t be programming”.
http://programmingisterrible.com/post/76953953784/programming-with-bui…
davexunit · 2015-12-29
>We love Ruby's efficiency for writing code.
Ruby's syntax is one of the worst parts of Ruby. [0]
>We love C's efficiency for running code.
Many other languages have efficient native code compilers, too. I don't know why people assume this is only a C thing.
>We want the best of both worlds.
>We want the compiler to understand what we mean without having to specify types everywhere.
This is good. I much prefer dynamic languages to static ones. Though I don't know if Crystal supports the best parts of dynamic languages like runtime program modification AKA live coding.
>We want full OOP.
Single paradigm languages feel very restrictive to me. I like languages that support many paradigms because different parts of programs call for different programming techniques. OOP in particular is a paradigm that I feel forced to use more often than I feel it's the right technique for the task at hand.
[0] http://programmingisterrible.com/post/42432568185/how-to-parse-ruby
Widdershin · 2015-07-06
http://programmingisterrible.com/post/39438834308/distributed-social-n…
The practical and social problems of distributed/decentralized social networks seems to far outweigh the gains in terms of anti-censorship/network resilience.
Reddit already suffers from a thing known as 'karma whoring', where users will work hard simply to gain karma points, often to the detriment of the quality of the community they're interacting with.
Karma points have absolutely no financial benefit or real worth outside of the status some internet denizens attach to them. I have struggled to imagine a single way of introducing financial incentives for Reddit participation that wouldn't ultimately fall prey to this.
It's also hard to conceive how moderation/curation might work in a distributed/decentralized system.
To put it simply, I've come to the conclusion that censorship is an often required tool in creating internet communities where everyone can feel welcome and safe.
I'm not sure how that would work in a distributed system.
Context:
I had this idea a while ago and started trying to write it. I really hope something comes out of all of the different approaches people are taking to this problem.
oblique63 · 2013-06-06
This isn't a negative, self-worth thing, it's a perspective thing.
What the OP here is describing, is exactly the mentality that leads to this nonsense: http://programmingisterrible.com/post/50421878989/come-here-and-work-o…
A lot of people would agree that empathy is one of the large components of what makes us "human", and that's rather vague, but it does make evolutionary sense for why empathy is useful for societal progress. And guess what, perspective is crucial for empathy. If we assume for a minute that almost nobody really lacks empathy, then what could be the only possible factor that produces an outcome like the one described in that link above? I'm sure most of us tech people aren't narcissists/sociopaths, so the only thing that could explain it is a skewed perspective that makes it permissible to rationalize a lot of the nonsense around us as being 'okay', or 'not relevant' to us. Empathy is a function that takes perspective as an argument, and if we assume that our empathy functions are correct (no reason to think they aren't usually), shouldn't it be good when we realize it's giving us the 'wrong outputs', and then do something actionable about it like try changing our perspective (or input)? I've battled with a lot of self-criticism and depression myself, but I see nothing wrong with this. On the contrary, it seems like the healthiest thing we could do as we approach a possible 'bubble' scenario.
I think the problem is…
voiceofunreason · 2026-04-21
bheadmaster · 2023-08-29
There's a very good quote on a programming blog [0] that I enjoyed reading:
Repeat yourself to avoid creating dependencies, but don’t repeat yourself to manage them.
[0] https://programmingisterrible.com/post/139222674273/write-code-that-is…
dunk010 · 2023-08-25
Reminds me of this: https://programmingisterrible.com/post/139222674273/write-code-that-is…
“Write code that is easy to delete, not easy to extend.”
gonzo41 · 2023-01-05
iwwr · 2022-07-07
Write code that is easy to delete: https://programmingisterrible.com/post/139222674273/how-to-write-dispo…
sagichmal · 2021-08-03
> When you bring in technologies like Kafka to orchestrate this, you'll end up with a more reliable system that you can fix if something goes wrong.
It depends...
If your services are servicing typical user requests, and expect responses in O(<1s), then eventing architectures are exactly the opposite of what you want. Using message brokers (Kafka) as an ersatz network layer is the path to sadness -- you want backpressure, RPC semantics, etc.
https://programmingisterrible.com/post/162346490883/how-do-you-cut-a-m…
If you're doing ETC/event semantics, the game is different. But very few orgs actually work that way.
piaste · 2021-05-17
> simple — It solves my use case.
> opinionated — I don’t believe that your use case exists.
> elegant — The only use case is making me feel smart.
> lightweight — I don’t understand the use-cases the alternatives solve.
https://programmingisterrible.com/post/65781074112/devils-dictionary-o…
zephyrfalcon · 2021-01-17
On the other hand, Richard O'Keefe claims in _The Craft of Prolog_, that "elegance is not optional":
"""
Elegance is not optional.
There is no tension between writing a beautiful program and writing an efficient program. If your code is ugly, the chances are that you either don’t understand your problem or you don’t understand your programming language, and in neither case does your code stand much chance of being efficient. In order to ensure that your program is efficient, you need to know what it is doing, and if your code is ugly, you will find it hard to analyse.
"""
https://programmingisterrible.com/post/39499310419/elegance-is-not-opt…
mysterydip · 2020-10-30
I wish seeing the name Dijkstra didn't immediately remind me of his oft-quoted BASIC comment:
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
The problem is it's quoted regardless of how much the BASIC dialect being discussed resembles the one he was talking about [1]. There are lots of good BASIC languages out there running all kinds of useful software that are dismissed out of hand by a subset of developers simply from that comment.
[1] https://programmingisterrible.com/post/40132515169/dijkstra-basic
wsc981 · 2020-09-06
My father owned a TI-99/4A and used it to teach me some programming. Afterwards I mostly just copied listings from the TI-jdingen magazine (published by the Dutch TI users group TIGG [0]). Together with my dad I also made a small game. Nothing to impressive. Basically just a ship that automatically moved from the left to the right side of the screen. The player could press a button to shoot a projectile on randomly generated airplanes that would fly from right to left.
I know Edsger Dijkstra considered the BASIC language to cause brain damage [1], but still at times I feel like it would be nice to program in a language like TI-BASIC again, just modernised a bit.
---
[0]: http://www.ti-99.nl
[1]: https://programmingisterrible.com/post/40132515169/dijkstra-basic
boltzmannbrain · 2020-03-18
"Write code that is easy to delete"
https://programmingisterrible.com/post/139222674273/write-code-that-is…
develop7 · 2020-01-12
> lightweight — I don’t understand the use-cases the alternatives solve.
© https://programmingisterrible.com/post/65781074112/devils-dictionary-o…