Even in those fields that people imagine involve a lot of perfection, like watercolors or fine Japanese carpentry, the perfection is not arrived at by agonizing over details and overworking the piece. The perfection comes from the muscle memory of someone who has done it many times. App development should be the same way.
This economy of effort is intrinsic to any craft and is part of being a good craftsperson. I used to have an attitude similar to the author, a mixture of derision and envy towards those who were able to ship. She needs to learn that if she does not abandon this counterproductive mental handicap, she will never be a good craftsperson, in software or anything else.
Software falls over all the time, often in very avoidable ways that give the impression of simple laziness and/or incompetence.
E.g. Why do I need to use Safari to log into my bank account? I bank with a household name bank in the UK, but they've failed to make their web portal work with Chrome.
Why does iTunes let me set up a new iPad, but at the end of the process I get a choice between two buttons labelled "Sync" and "Done" - and I still have no idea what either is supposed to do, because sometimes I get a message about syncing to an old backup, or something, and the whole process is utterly counterintuitive.
Why can't operating systems handle paths with spaces or unicode with a standard convention for quoting that ensures consistency? It's 2016, not 1966, and this shouldn't even be a problem. But it is, for a lot of languages and operating systems.
And so on. IMO the author is right. We have a "dog ate my homework" industry made of quick superficial hacks bodged together, when we should have an industry built on solidly professional standards, conventions, and expectations.
Yes, the hacks ship. But if they don't work, how is that a success?
The attitude is built into the culture, and it shouldn't be. It should be impossible for anyone to become a professional dev without some lectures or lessons in domain analysis that forces them to confront a fundamental lesson - the problem is always harder and more complicated than you think it is.
A talent for cute math and logic problems is not the same thing as being able to dive into a novel domain, extract the essential elements, design a workable architecture to represent the elements, and then iterate towards a robust solution that can survive contact with users.
The median house will be used for decades, the median software is used for months (maybe days, or even minutes). This is really what my point is.
I reckon in most companies, software is written and maintained until the whole system it's a part of becomes obsolete. That typically takes years, sometimes decades if the system is really useful.
It's really risky to rewrite software, so it typically isn't done; it's similar with deletion of code. Most people shy away from it because they're making local changes and don't have enough global knowledge to be brave. So the code lives on.
Personally, in my professional career, nothing I've written has yet been retired or end of lifed, and I've been doing it for 15 years. Some things were experimental and never got released; some things were maintenance for a subsystem that got buried away; but no whole feature nor whole product has been discarded other than by gradual overwriting through maintenance.
This may be true for trivial web apps, but line-of-business software is often used for years, sometimes decades.
I find the beauty of code is not in adhering to someones concept of elegantly written code, that only the coders see, but in the fact that it's living, and that over time your solution can evolve to become better than its intended purpose. Something observed to be perfect usually has a past that is often overlooked.
I think the attitude of doing less things better is quite common among successful software developers. It's just hard these days to have a good experience while getting to a level where these values matter.
They don't, but a good carpenter is not going to try to figure out how to make every single wall perfectly 90 degrees, etc. He's going to take a level, see if the thing is in a center for a given stud, make that work, and then move on.
They never perfect the end result. None of the walls in your house are likely perfectly square and plumb They also use imperfect building materials, and so they know that a year from now, even if it was square, it wouldn't be anymore.
Carpenters, more than anyone, are true believers in "good enough". I'd argue most of your other examples are the same.
That said, the problem she complains about is real. She is, in essence, a programmer from 30-40 years ago.
When you had to share time on computers, and your software broke, you didn't just poke it repeatedly until it worked, because you couldn't. Instead, you sat on a mountain and meditated upon your code, until you understood it well enough to fix the problem and try again.
In that sense, the thing that has really changed is not the cost, it's the speed at which you can throw shit at the wall.
Development is so fast nowadays that programmers don't stop to think about the real underlying problem, they just want to make the compiler shut up or the program keep going.
They just want to solve whatever their immediate problem is.
The cost incentive was always there. People always wanted good software as fast as it could be built. It was the speed of being able to build it that made people concerned with quality.
Now that they can essentially build it at light speed, nobody cares, because it's only how it seems to work that matters.
IE doing things the wrong way to achieve the result people want is fine, even if it causes longer term problems.
You can see this in pretty much any long-running (IE 15+ year) open source project.
:)
So yeah, it was entirely possible they didn't introduce more bugs.
Now people just expect to crash often and make it up in volume.
They can of course, which is precisely the problem the original author has: in a ton of contexts, fast and able to hack up things is more sellable than understanding problems.
(and FWIW, i actually haven't thought hard enough about it to have an opinion whether the current status is better or worse, i'm just explaining why it's not necessarily about cost to develop).
In places where failures are expensive, such as high volume websites, we use techniques such as A/B testing to limit the scope of expense of failures and detect them earlier.
In cases where failure is truly unacceptable we take more drastic measures such as formal verification, restricting programmer freedom through coding standards, etc.
Even he dramatic story about having a wrong number read out on NPR you'll notice she is the one punishing herself; no-one really admonishes her, there are no negative repercussions. As economic pressures have increased in journalism, this attitude that everything must be fact checked has fallen by the wayside since it is not economically viable any more. This economic pressure coincides with mass adoption of the internet though, and the real cause may not just be their declining ad revenue, but the increased competition between news outlets to be first, since that's what drives clicks.
The saying that the perfect is the enemy of the good exists for a reason.
Although we may have formal engineering education, most of us end up making business logic where there are few rules on how to do it. You can't compare it with building a bridge, which has a strict mathematical workflow.
The use of the word "still" here implies that it will be, or that it should be, more "science" than "art". As an act of creation and navigating ever changing constraints, I think it is more art, and will have art be a major component of it for a long time, if not forever.
Building 90% of a software is easy, getting to 100% is insanely difficult.
Building 90% of a construction/hardware/car/... is hard, the final bits are easy.
Finishing always requires more attention to detail, and a tougher sense of good-enough than the first 90%.
Of course, the definition of "perfect" is different for everyone. The point is that craftsmen can wait until they're fully satisfied with what they are working on before releasing it. Engineers don't have that luxury.
If I build a house with a bad frame, it's really hard to make it better over time. If I build a quick MVP, I can easily incrementally improve it.
But sure, it'll be different this time.
If you can code something quickly and well enough that it doesn't immediately collapse under its own weight, you have succeeded. The fact that a codebase has existed long enough to become "legacy" means it did a good enough job to stay alive.
I don't think that's fair to a large number of engineers. We know that code gets loaded with technical debt and we know that we can't spend time fixing it because of "business realities". That doesn't mean it isn't a problem for us though. Anyone whose had to maintain a codebase that's years old and riddled with undocumented and untested "features" suffers for it. Old code is a source of stress and anxiety. It might make money, but that isn't a reason to think it's not an issue.
Far from. The worry is not "this code is old." Plenty of old code (especially boring old code) is cranking along just fine.
The worry is that if an old, abstruse system stops working or has a critical security bug, there's a real risk that nobody will be able to put the fire out.
Well, yeah, for the first version. But when is the first version also the last one? Not in many good situations. Crap that doesn't immediately collapse under its own weight will probably immediately collapse as soon as you add more weight to it in version 2.
A lack of anxiety about the structure of the product is myopic and ignorant of engineering realities. There's got to be a balance. Too little anxiety, and you lose customers to competitors that spent more time to build a quality product, structured so that it's easier to grow. Too much anxiety, and you're in a "perfect is the enemy of good" situation, and you'll lose customers to competitors that were able to iterate faster and with a proper balance.
But you won't. Even if you want to, the client won't pay you to because all the client sees a working solution, so you never get the chance to.
That's the problem the author is highlighting.
Code "quality" (whatever bullshit metric you use for that) is not the only metric of improvement. In fact, it's probably the least important metric to optimize over time.
Usually that's new features and bug fixes. It's very rare to find a client who'll happily pay for refactoring. If you're in a job where you get time for that you should consider yourself very lucky indeed.
EDIT: For what it's worth, I agree with your point about code quality. What's 'beautiful' now is only 'perfect' in the frame of the current feature set. It might be horrible if the next feature that comes along changes things dramatically. I'm very much of the opinion that "good is better than perfect", just with the addendum that the code at least has to be good. Bad code is just bad.
Why do software engineers break this mold? I think it's because building software is inherently cheap, which means it's easy for a large number of people to build things without an obvious economic incentive, which means there's often a product misalignment. When someone builds a house or a car, they are certain their product will get used. Most software, on the other hand, never sees heavy use. Probably 90% of what I've built over my career has never been used, and I've had a productive career.
The most rational thing in software is to ship something functional, then perfect it after it's been proven to be useful and popular. I can see why someone with a craftsman's mind would hate this. I feel a sort of disgust with myself when I ship shitty code, but ultimately I know it's what makes me so productive and valuable to my employers. This disconnect is real, and it's worth talking about.