Software - It's not what you think it is - Part 5

Invisibility and malleability leading people astray

Uwe Friedrichsen

10 minute read

Group of resting collared peccaries

Software - It’s not what you think it is - Part 5

In the previous post, we discussed the value preservation dilemma of software. We have seen that software – opposed to almost all physical goods – needs to be changed and adapted to the ever-changing needs and demands of its environment to preserve its value.

In this post, we will look at the final two issues of software I would like to discuss in this blog series, the invisibility dilemma and the malleability curse. Let us start with the invisibility dilemma.

The invisibility dilemma

I already wrote a post about the software invisibility dilemma a while ago, yet in a different context. Still, let us repeat Fred Brooks’ quote from his famous essay “No silver bullet” 1 where he identified invisibility as one of the issues that makes writing (good) software hard:

Invisibility. Software is invisible and unvisualizable. Geometric abstractions are powerful tools. The floor plan of a building helps both architect and client evaluate spaces, traffic flows, and views. Contradictions become obvious, omissions can be caught. Scale drawings of mechanical parts and stick-figure models of molecules, although abstractions, serve the same purpose. A geometric reality is captured in a geometric abstraction.

The reality of software is not inherently embedded in space. Hence it has no ready geometric representation in the way that land has maps, […]

In spite of progress in restricting and simplifying the structures of software, they remain inherently unvisualizable, thus depriving the mind of some of its most powerful conceptual tools. This lack not only impedes the process of design within one mind, it severely hinders communication among minds.

This leads to situations, I described in the previous post:

In software we see cargo ships powered by jet engines connected to wings attached to the ship. The steering wheel and transmission are still from the sports car and for some unclear reasons you still need to be able to attach child safety seats all across the cargo holds.

While the software is changed to adapt to the changed needs and demands of its environment, people often forget to remove solution parts that are not needed anymore. As software is invisible, nobody notices it. And even if some frustrated software engineers repeatedly point out that such leftovers should be removed from the software, nobody else cares because nobody except the software engineers sees it. Even the software engineers only see it in the code. In the running software, the leftovers usually remain invisible (even though they may affect the behavior of the system in unexpected, “inexplicable” ways).

But the invisibility does not only lead to leftovers in code. It also leads to highly contradictory, fragile or even dangerous solutions which are not questioned by anyone because nobody can see the problem. 2

Figuratively speaking, with software you can design and build a skyscraper standing on the tip of a needle that will fall over and crash as soon as anything touches it and nobody would realize it before it falls over. Hopefully, the tests would reveal the issue. Still, it would go unnoticed until you start testing. 3

If a house-building architect would show you a design with a skyscraper standing on the tip of a needle or the entry door at the 52nd floor, you would immediately notice the design does not make any sense and reject it. The same is true regarding requirements: A client would not require a house design that would let the house crash as soon as anything touches it. This is because a house can be properly visualized and the visualization helps to reason about the feasibility of the final product.

In software design, we lack such a visualization – especially one that not only supports us in reasoning about a solution design but which also lets us discuss the required solution properties with the requirer. Sure, we have ways to visualize our solution designs like, e.g., UML but they are of quite limited use – especially regarding discussions with the requirer.

We may use such tools to visualize a package structure but what does it tell us about runtime properties? Also deployment diagrams usually do not reveal any runtime properties. Often, people even like to leave out the lines between the boxes because that would make the diagrams “incomprehensible”. Well, maybe that would be a sensible starting point for reasoning about our designs. Or are they incomprehensible because we lack the possibility to properly visualize software?

No matter how we turn it, we lack the possibility to visualize software in a way that enables us to reason about its feasibility and properties at runtime and to properly reason about the implications of a design and implementation change. The tools we have are crutches at best. The invisibility of software and its very indirect way of affecting its environment makes it hard, if not impossible to properly visualize it and reason about it based on the visualization.

The malleability curse

If this were not hard enough, we additionally suffer from the malleability curse of software. Software can be bent and twisted in ways and still do some (seemingly) useful work that is impossible with any physical materials. Figuratively speaking, we can take away the wheels of a race car, mount two halfway round rocks as front left and rear right wheel and then race with 300 km/h. Somehow, this does work. Of course, we will badly crash as soon as we touch the steering wheel. Still, on a straight road we could race this way with software.

We can also build airplanes from bricks and mortar and submarines from cardboard with software and somehow the plane would fly and the submarine would dive. We can turn roof windows into doors and a kennel into a supermarket. We can build heating systems from hairdryers and attach a plow to a race car. It is all possible with software. It may work poorly. It may be brittle. It may crash as soon as you leave the happy path. It often results in a huge waste of resources. It may be incomprehensible and thus unchangeable. But somehow it does work because software is so malleable that you can do all those types of things with it.

And such things are done with software – over and over again. As nobody can see what nonsense they often request and implement, software is bent, twisted and mutilated beyond recognition all the time. Software is invisible and not subject to the laws of physics. You do not see that if you stretch a kennel to become a skyscraper that the skyscraper walls will be made out of 0.01 mm thick wood which shatter as soon as the slightest breeze caresses it.

As a result, requirements are made that go against all principles of the design and implementation of the existing software. Nonsensical designs are created just for their own sake, not solving any of the given problems, often wasting huge amounts of resources. And tons of “opinionated” or careless implementations are made that quickly let systems deteriorate in a plethora of workarounds, violations of design guidelines, implementations deviating from everything else, resulting in the dreaded “big ball of mud”.

While this may sound harsh, it is the reality of software more often than it is not. Efficiency, productivity, velocity and feature burn-down rule the software development world. More is better. We try to tackle the unpredictability of post-industrial markets with implementing more features more efficiently which is doomed to fail. And so we create painfully twisted software behemoths, all with the best of intentions. 4

But somehow these behemoths still work. They are a huge steaming mess, long beyond repair, but somehow they work. Well, not always, but operations figured out how to navigate their shortcomings, restarting the servers every night, tweaking the database to support the broken access schemes, upgrading the client machines to 64 GB (which is still a lot at the time of writing) and using lots of duct tape and WD-40.

Or as I tend to say:

If people could see what steaming piles of (software) crap they rely on, entrust their well-being and sometimes even their lives to, they would run away screaming.

While the malleability of software is one of its greatest properties, in combination with its invisibility it often degenerates into a curse.

Fifth interlude

In this post, we discussed that software is invisible which deprives humans from an essential reasoning instrument. We also looked at the malleability curse, the property of software that it can be bent and twisted in totally absurd and nonsensical ways while still somehow working. In combination, this often leads to poorly designed and written software without anybody noticing it until it is too late 5.

What does that mean for an AI solution that is expected to write software? Well, not so much in the first place. An AI solution does not care about the invisibility of software and the malleability of software gives it more options.

Still, it will need to deal with software that was created abusing the malleability of software without the option to see what has been done. It will need to deal with highly absurd, nonsensical, wasteful and mostly dysfunctional code. It will need to understand it and modify it (good luck with that beyond relatively isolated pieces of functionality).

And – which adds a subtle layer of irony – it is trained on huge amounts of highly absurd, nonsensical, wasteful and mostly dysfunctional code because big parts of the code that was used to train the AI solutions fell prey to the invisibility dilemma and the malleability curse. Well, guess what code the AI solution will generate? Exactly!

But I think the much bigger problem are the effects that all the misconceptions described in this blog series have in combination – for AI solutions as well as for the humans affected by software. This will be the topics of the remaining two posts of this series. In the next post (link will follow), we will summarize the implications of the misconceptions for AI solutions. Stay tuned …


  1. In case you do not want to download the paper from ResearchGate: if you search for the paper in the Internet, you will find it in various places. It is also part of the essay collection The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition) by Fred Brooks. ↩︎

  2. Except maybe some software engineer who detects the problem somehow in the pile of source code – yet without any clear visualization that supports the engineer. This is mostly as if a powertrain designer needs to decide if an engine works as expected based on a written specification of the engine without any images – text only. ↩︎

  3. And depending on the tests, it may even remain unnoticed during testing – not because the tests are necessarily bad but because the software skyscraper may need to be touched in a specific way to fall over which the tests unfortunately do not cover. ↩︎

  4. To be clear: I do not assume any bad or even malevolent intentions of any of the involved actors. Maybe an inflated ego sometimes gets in the way, but basically I assume everyone acts with the best of intentions. ↩︎

  5. Again, maybe some software engineer notices the problems. However, most of the time their objections are ignored because “those folks always complain if their code is anything less than perfect”. Well, sometimes they might be a bit too perfectionist, but often they are the only persons who see how crappy and fragile the software is … ↩︎