Some of the responses to Software is Synthetic included surprise at how the word is used. So what does it mean to be “synthetic”?
Firstly, we should understand “synthetic” in the classical sense, in how we come to know our world.
In this sense, it is a mode of inquiry, a method of solving problems, a way of understanding that uses experience, testing, and experimentation to gather knowledge.
This is how the word was used by the philosophical giants- Kant, Hegel, and Wittgenstein. They put it in opposition to “analytic”:
- To be analytic is to work with what is knowable independent from experience, which is the basis of logic, mathematics, and philosophy.
- To be synthetic is to know through experience, to gather information from the world, to synthesize understanding from what we learn.
This is also how the word was used by the early programmers, in the 1940s and ’50s when, they discovered the medium of code, and began using an experiential approach to solve math problems. “Synthetic mathematics,” they called it, playing with algorithms to test hypotheses and generate proofs from data, not formula.
Western society was, for centuries, firmly devoted to the analytic approach, — the presumption that we can root out all the formulae that underly the world, and understand it completely. To that end, analytic thinking favors in-depth planning and formal proofs, and it has dominated the culture of technology long before the invention of computers.
But modern software development has reversed the presumption, and Agile methods have emerged as a practice of synthetic thinking, a commitment to the value of experiencing our work.
When we solve problems with software, we primarily manage our work using this approach: if we want to find out if something will work, we need to see it, we need to experience it – this is how we come to know and understand what we are creating.
Here we have the standard usage of the word today – the result of synthesis, the process of bringing together parts to form a unique whole, creating something new. In this sense, to be “synthetic” is to be a compound of simple elements, constructed intentionally, built for a purpose.
On the one hand you might think materials, plastics or petrochemicals, and yes, to be synthetic connotes something artificial, not occurring naturally.
On the other hand, also think of systems of all kinds, mechanical systems like engines or factories, or social systems like government and businesses.
Either way, these “things” are the result of synthesis, bringing together discrete parts that unlock capabilities when they work together. Our lives are deeply entwined with them, we work with them, we are a part of them, they shape our lives.
But understanding them? Figuring out how to use them or how to change them? That’s another story.
Systems Thinking has sprung up in the last century as an effort to understand the dynamics of the phenomena in which we live and work. The discipline studies how systems change, what forces operate on them, and why they change in unexpected ways.
The big idea is: systems are composed of many parts, but those parts do not define them, and, most importantly, they cannot be fully predicted by an analysis of those parts. To know a system, we need to look not at its parts but rather what it is a part of. To learn how to change a system, we return to the classic definition of our word: we need to use the synthetic approach to problem-solving.
What makes software unique is that our materials are also synthetic. In other words, the parts that our systems are composed of are themselves artificial, unlike systems of the world, which rest of the stable structures of reality. In many of its forms, modern software development is able to detach from and ignore the laws of physics that govern the hardware it runs on. This means that we are not bound by the same kinds of constraints that guide creation in the physical world.
In software, we assemble our forces, create our atomicities, and build upon these invented dynamics. Our systems malleable, properties easily changeable, emerging and decaying. I have often heard experienced software engineers telling their product managers, “Its just software, we can make the system do anything you want.” We are not bound by ‘rules’ other than the ones we create for ourselves. Don’t like ’em? Create new rules. They are only a pull request away.
Finally, software is synthetic in the post-modern sense, in terms of our context: human, all too human. We should not see people as independent of technology. We should understand our systems as cybernetic – part social, part technical, a symbiosis of interconnected forces.
The boundaries between code, infrastructure, tools, people, and organizations are blurred and constantly shifting. Different parts of the system need to be learning from each other, trying to build off the properties that emerge as boundaries shift and interactions create new possibilities.
Here is where the “create new rules” part of software becomes interesting. We created many of our rules through collective decisions. Take for example our core networking protocols like TCP or DNS. These have grown through the RFC process and have not changed much in the last 20 years. Some of these protocols are despised and antiquated, arcane and unworkable, and yes, nearly impossible to change.
We can change these rules insofar as we can influence the social part of our systems to use them. Despite the emergence of newer and arguably better networking protocols, we can’t use them unless everyone is using them, and adoption is very, very hard. So here we are, our cybernetic constraints become the limits to our synthetic systems. We are become locked in to using relatively ancient technology.
This comes up on both is way many of our management practices in software are now focused on how to create software systems that can be successfully (joyfully!) maintained for years.
The synthetic nature of software dominates it.
Every component is developed in a unique context that shapes its existence in its system, an intentional existence, tied to a particular mode of understanding.
Every change to a component must be evaluated by experiencing it is as part of a system to understand the “why” behind it.
The development of modern software is a practice of navigating through this complex web of whys, weaving them together into systems that solve our very human problems, subject to all the limitations that we would expect to find in our very human existence.