Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
How to think about software quality (2022) (evalapply.org)
52 points by adityaathalye 13 hours ago | hide | past | favorite | 44 comments
 help



This article is very rambling and somehow manages to miss the most important driver of reduced software quality: shifting requirements.

You can have the most beautiful perfect design that leverages the greatest abstractions in the world, and then have it all entirely destroyed by a single requirement shift that totally kills your abstractions.


Post author here. Guilty as charged re: rambling. Brevity is not my strong suit.

To the second point, I'd say I'm in violent agreement with you. In fact, my whole thesis is that because software mutates all the time, it is observed that successful software mutates successfully.

Obnoxiously quoting self:

> Unlike all other machines, it is pure concept, and as such it is infinitely malleable and mutable. And mutate it does, all the time.

and several paragraphs below that...

> Not only does all software mutate, we also end up performing all kinds of deep surgery on the organisation that produces it. The whole thing—product and org—is simultaneously flexed, reconfigured, and even totally redesigned in-place with rapidity that is very uncommon in other industries. Why? Because software fundamentally is peoples' thoughts being played on repeat.


well you cannot design for the unpredictable, but well designed code will make refactoring easier anyways

If the design is so inflexible that a single requirement shift destroys it, then it wasn't a good design.

That's a refutation of agile, Vibe Coding and the last 25 years of the software industry.

One of my own quality metrics that almost everyone rejects is a "a good design is a design where a change that seems like a small change to management is... a small change"

It plays out like this. To get to product-market fit you are going to have to zig and zag 20 times. Everybody optimizes for the first step of this journey and then on the second step they optimize for that... and by step 5 or so the archiecture is exhausted and you have no hope of getting to step 20. The rare team that is looking ahead 20 steps is the one that survives.


The problem is that you don't know in advance what the 20 steps will be, and you may spend time solving the wrong problem.

Make step 1 as simple as possible, step 1 is small and changes are cheap, you can even rewrite everything with little effort, no need to prepare for anything at this point.

Step 2-4 will inevitably break something, no big deal, rewrite the parts that need to be rewritten, it is still cheap.

At step 5 rewrites are starting to get costly, but now you have a better idea of what is here to stay, so it is now time to invest in things like regression testing, style guides, etc...

At step 10, you have quite a history, rewrites become a really bad idea, no turning back after that. So now it is time to think about the future. The difference from doing that in step 1 is that you now have 10 steps of experience and only need to look ahead 10 steps.


>It plays out like this. To get to product-market fit you are going to have to zig and zag 20 times. Everybody optimizes for the first step of this journey and then on the second step they optimize for that... and by step 5 or so the archiecture is exhausted and you have no hope of getting to step 20.

It not being "exhausted" is just what distinguishes a good programmer from a bad one. If you're good you can keep a lid on tech debt in the face of rapidly changing requirements. If you suck at it, well... you can't.

>The rare team that is looking ahead 20 steps is the one that survives.

lol no good software engineering means assuming that you don't have a crystal ball (because you never will) and building accordingly.

This usually means YAGNI, minimizing up front design and refactoring aggressively. These are the things that keep you agile enough to move in many different potential directions in response to different potential futures.

The time when this really got rammed home for me was working on a startup where a political black swan event ended up changing key requirements of our software overnight. This pulled the optimal architecture in a wildly different direction to where we anticipated it was going in the previous week.


> If you're good you can keep a lid on tech debt in the face of rapidly changing requirements. If you suck at it, well... you can't.

Every drop of tech debt (aside from AI slop) I have ever been a part of has manifested simply because some manager or executive made the decision to sacrifice quality for short-term speed. Sometimes this looks like an unskilled developers producing something that management won't let you fix. Sometimes it's a completely unrealistic deadline that requires extreme measures to meet. If you are able to keep a lid on tech debug in the face of rapidly changing requirements, it likely means that you have enough slack in your job to do so.


Nope not true at all (30+ years of experience here working on very large scale software).

The whole point of being agile is to design your software architecture to be agile. That's what I do. And it works.


Then I guess no design is good. Here's an easy example: take any software system you can think of. Let's add a single new requirement: it must produce an output in 1us. I'll bet your system has to change.

Well that's a pretty contrived example. There are fair amount of requirements that can be predicted as "possibly coming" in a given problem space, and a good design typically takes them into consideration and plans contingencies such that a design doesn't crumble.

It's extreme to demonstrate the point, but it's not contrived. Realtime deadlines are a completely normal requirement for the systems I work on. I have change reqs on my desk right now that specify a full reboot back to network responsiveness in <=300ms. That definitely changes how the system is designed.

It being extreme is what makes it contrived.

It's also a requirement programmers often overemphasise due to the McNamara fallacy.


Contrived does not mean unrealistic. I have seen many extreme requirements come down on short notice. Over time, the peter priciple guarantees that there will be a middle manager that miscommunicates an agenda they dont fully understand, then push an emergency change down the hierarchy.

Right, the point is that GP's definition should take the nuance you mention into account (namely, that some types of changes are more likely, and thus more important to handle nicely, than others).

I think you are interpreting his claim in the most extreme possible way. You are doing the equivalent of asking a civil engineer what if his bridge needs to support flying cars, or weight half as much while carrying ten times the load. Of course there are architecture breaking requirements, but his point still stands for reasonable and foreseeable changes. If it doesn't survive that, then it wasn't a good design begin with.

Completely untrue. Every design can be destroyed by a single poorly-thought out requirement. I can take down Facebook's design just by saying "any edit must immediately be visible to all users".

That's a straw man argument. Your new requirement is physically impossible. No software team can break the laws of physics.

So the real question is what exactly do you mean by "immediately"? There are many answers with different pros/cons and cost. And I bet the solution won't impact 99% of the software Facebook has already written.


If that ever happens to you, you're doing it wrong.

I've spent 30+ years building large-scale software, and it has never happened to me. Good software design lets you accommodate even major requirement changes with minimal changes to the code.


If you're using Lisp, then sure. If you're using C++, then chances are you're going to have to heavily overengineer the thing to cover all possible requirement changes. That comes at a great cost - in most cases, you are unlikely to benefit from the overly abstract design, but you will pay for that additional complexity for the life of the project. I am convinced that you are better off designing the project to solve the problem in front of you, and then if the requirements shift, pay the cost to solve the new problem, rather than forever pay the cost of solving a host of unrealized problems.

If there is a place that is hiring and cares about Software Quality, I'll take a 70% paycut to work there.

You would have liked the last place I worked before retirement. Full-on software test team and everything. Private offices, too. Don't get me wrong, there were warts (oh, were there warts), but overall it was a good time. It wasn't a 70% pay cut, but the cut was considerable in comparison to what I was accustomed to. I didn't care, I was nearing retirement, and my "I'd take a pay cut if..." was the aforementioned private office.

But the company got sold to a conglomerate before I left, so I can't guarantee that culture is still there.


Why are people so reticent to name companies, even when they're praising them?

It can be seen as dark advertising. Because it is.

Because signaling is more important to them than helping

I've just accepted the fact that every tech company is just a dumpster fire.

Some are dumpster fires inside oil spill fires on top of a lethally radioactive surface. Once I had such a client from the depths of hell. Handling lower/middle-income people's wealth. Doing money math with floating point arithmetic. In Javascript. Minimum "function" line size of one hundred lines, with several four hundred line "functions". With "functional" idioms like map/filter etc. inside said functions, except hang on why is the mapping function making network calls? To a workflow orchestrator? Which is then calling out into... mongodb. To... do the money math based on a flag in the `meta` field of a user object. A flag that is being set and reset at least twice, directly in the four hundred line function I'm staring at with bleeding eyes, and, but I can't bear to jump to definitions and see where else it might be toggled from the calling code? Please don't make me do it.

Um, and this was just one aspect of their software organisation.

Four hundred line floating point dumpster fires, inside a gawdawful dog-slow software system, because, nearly a hundred "microservices" (about two per engineer, I counted), being somehow managed via an elaborate AI of calendar tetris, because everyone in the company was somehow fine with it, because they were mostly young and it was their first or second job and they probably didn't know any different, the poor sods.


Plot twist: Newly-hired head honcho of software was going to fix it all with Kubernetes. Peak transaction volumes of about ten per minute.

Once the project ended, I never looked back and wiped all but the essential lessons from memory.

I can't name them because my brain legit refuses to look up the name. I know it's there somewhere in the periphery. And even if it did pop back, it shall remain nameless, for harm could come to many innocents.


Gene Kim wrote the DevOps Handbook and I think was at least involved in the related DORA and Phoenix Project and Unicorn Project office narrative books. Between those and the Google SRE book, I feel very well placed to have continuing value in the SDLC pipeline for wrangling the oncoming armies of Jr Developers-as-AI-agents-and-sometimes-humans into alignment. I also recommend System Design Interview 1 and 2 books by Xu for logical system design refurbishment, Designing Data Intensive Applications for most company programs, and Hexagonal Architecture Explained by Cockburn for finally getting something as small as a class or module to something as large as an entire Information System to have clear modular boundaries, without needing to do fuzzy pattern matching around half-remembered SOLID principles and GoF design patterns or trying to blindly apply 12 factor app design principles.

Quality used to take a back seat because there was so much legwork to do. AI has reduced the cost to be excellent, so let's be as excellent as our environments let us.


Great book recommendations (I have read parts of the Google SRE book and Designing Data Intensive Applications)! I will also add a couple gems that I don't see often-cited: Simple Object-Oriented Design by Mauricio Aniche and Secure by Design by Dan Bergh Johnsson, Daniel Deogun, and Daniel Sawano. Both have a lot to offer in terms of software design and maintaining complexity. I also liked Refactoring to Patterns by Joshua Kerievsky.

Quality is what we call the difference between what succeeds and what we wish succeeded. It's a measure of how closely the opinion of the person saying "quality" aligns with what is actually rewarded by the fitness function that objectively exists. The only thing you've learned when you hear "quality" is what the speaker thinks is good, not anything about the subject.

Quality does not exist until a (person, preference, subject) pairing happens. It's not real. It's literally not a thing. It's just a name for mixing up your is and ought.

When someone saying "quality" can point to the specific property that makes the subject quality, they're almost always pointing to what is, from the perspective of the fitness function, inefficiency, a waste of energy and effort, more spent than the system rewards.

Anyone who spends a lot of effort building skills to get particular results is going to believe those results are important, at least a necessary part of success, if not the whole definition. When people who did not put in the effort keep succeeding without those results, "quality" becomes the cope. It's shoddy work. They did it wrong. They cheated somehow.

And yet they succeeded.

Because "quality" is what a person says when is and ought don't match, a fact about the speaker, not the subject.


I agree.

I think the only time quality might be objective is when there's a planned "ought", like a required feature that needs to be implemented later.

From that perspective, the "quality" could be measured in how easy it will be to implement that, in a "total effort" sense (subjective I suppose), where "low quality" might require a whole rewrite of big sections, where "high quality" would have the required stuffs in place (maybe abstractions, or maybe even placed where spaghetti would fit nicely) to make it "easy".


Yay! I've argued this a few times here and it's been, uh, perceived as low quality.

I think "objective quality" can always be re-framed in terms of fitness. "Quality" is just not anything the fitness function measures, so it can't.

It's hard to really make the case because of course there's something real that people mean, colloquially, and it's totally valid. Lots of things objectively have properties most people would agree show quality. That's where it is, it's right there!

But all those properties can be described without the use of "quality" by just reciting every fact about the thing. The only thing that will be left, the only thing you can't communicate that way, is what the person thinks about those facts.


Previously...

How to think about software quality (2022) - https://news.ycombinator.com/item?id=39490543 - Feb 2024 (66 comments)


Testing is not "Quality Assurance".

If I got nothing else out of TFA, at least I could raise my hands and shout an "amen!".


Friend!

Alas, having died on that hill one too many times, I can be with you in solidarity, but not on the hill. No, not again.


That’s great, but how do I fix my motorcycle?

Maybe we could take a page from the SWEBOK here, which contains a lot of previous thinking on this topic.

(2022)

(edited 2023) agreed mods should append a year given how fast things have been changing

Hey Siri, is my app doing what I wanted it to do?

Siri: Yes, but each action takes 10 minutes to resolve and your users are jumping out of their windows after dealing with your software.

Programmer: Great, my software works!


Hey Siri, my software isn't doing what I wanted it to do. Confirm PRD did not include 10 minute wait times and send my IQ test results again please.

Siri: brb, asking my agents... Hold my beer.



Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: