I agree that most programmers should not call themselves engineers , if your definition of « engineer » is limited to the design of bridges, ships or airplanes. After all, even if some places still have decades-old software running in a dusty corner, a legacy from a lost age of Software Engineering, modern programmers are recklessly patching together broken code and pushing it to production on a friday afternoon. Right?
No. Stop. Look beyond the title, beyond the blanket staments. There's a hidden question in that article, and it's a tough one to answer: why don't we design software like we design bridges?
The easy answer is that it costs too much, but it is a worthless answer that fits half of the « why don't we X? » questions and doesn't explain why it costs so much in the first place.
The wrong answer is that software is special. A bridge is not expected to withstand direct attacks, it does not require monthly updates to third-party dependencies that might break something, and the stakeholders do not ask for new bridge features or major changes in the middle of its construction and every one or two years afterwards.
Guess what? These things do happen with large engineering projects as well, and they end just as badly. To satisfy the excessive ambition of stakeholders, the Berlin Brandenburg airport project strayed from the well-traveled paths of airport building — that humans have gotten pretty good at in the last sixty years — and into a perpetually delayed, budget-guzzling fiasco. The changing requirements and never-ending feature requests also helped.
As for direct attacks, let's not forget that most security issues (buffer overflows, injections) are not the equivalent of dropping bombs on a bridge, but of driving your sedan over that bridge in a very precise way.
Large projects are costly when designed and built from scratch with an attention for detail and correctness, regardless of whether they are bridges or software. You have to invent new types of concrete and steel beams and foot-thick cables and screws, not because you like to invent new things but because existing designs do not fit your specifications. These are usually straightforward applications of well-known principles, but it takes effort to design them and fit them together. Effort costs man-years and man-years cost money.
Mainstream software doesn't build things from scratch. Sure, it may start with an empty Git repository, but it tends to reuse a lot. New projects seldom ask « do we write our own operating system? » or « is the standard library string implementation good enough? » and they rarely implement features that third party libraries can provide.
That's good, because it brings costs down and allows us to create software that will not need hundred-million-dollar returns to pay for itself. It is the Home Depot method of building bridges: find cheap, common materials with well-known properties and fit them together. And it works! You can cross a river with such a bridge.
Except the river cannot be too wide or too deep, and boats cannot pass under your bridge, and it will not hold anything heavier than a bike, and the plywood you picked will rot in a few years, so you'll have to replace it, and you will have to upgrade to a new version of screw when the supplier tells you that the old version is prone to breaking. But for a lot of software, this is perfectly acceptable.
Reuse has a price: you are now dependent on general-purpose components. For each line of code that you write, there are a thousand lines of code in the libraries, applications, scripts, drivers and operating systems that you depend on, out of which nine hundred are of no practical interest to you but still come with their security flaws and performance issues and critical bugs.
But reuse is a choice, not an inherent aspect of software development. You could use a micro-kernel instead of an operating system, you could pay your hardware provider for bespoke drivers tailored to your needs, you could write your own high-performance event-based HTTP server, you could outsource the crypto code to experts instead of using a free library from a penniless project.
You could cut off your computers from the internet, enforce code-data segregation at the processor level, invent your own deployment system so that a compromised USB key or network device cannot install a virus or backdoor.
If it was worth it — maybe if millions of lives were at stake and you were facing a determined attacker — then you would do it. Some projects do.