The All-Important Element of Software — Context
“But how does this help me make a video game?”
This was my reaction in high-school and early college to every introduction to programming that formal education threw at me (and you might as well count computer apps and some mathematics among those). Frustrated, I left every one of those classes with an acute understanding that “I still don’t know how to make that video game.”
What do Video Games Need?
I knew what a video game is. As a kid, I played many games on many different platforms. For the naive question of how to build one, any answer sufficiently complete for me to emulate some fraction of any of my favorite game titles would be sufficient.
Unfortunately, this just isn’t how the world works. In order to answer the question of “how can I make a video game”, we must face several layers of reality exposed in the answer:
- Firstly, we have the pedantic “technically correct” answer, which is never helpful.
- Secondly, we face the realistic constraints on deploying our solution to one of the ubiquitous but diverse computational machines or interfaces that we use.
- Thirdly, we must face the fundamental lack of competitiveness resultant from just answering the first and second components. At this point, we must confront the need for something that can be called a “framework”, a set of vendored software components and some generally accepted means of running those components together with the “actual game” code.
The pedantic answer is that the code needs some access to I/O mechanisms. To be able to manipulate these mechanisms in a satisfactory way, the code needs access to “lower level” functionalities either directly or indirectly because the machine is already running code called the OS and our task is to run our code inside of that code.
What The Courses Wanted to Teach
I speak for many entry-level students (although with many years of hind-sight available at this point) when I say that school absolutely did not provide me with these tools I longed for. School wasn’t even interested in doing so, and I never found that out until the class was basically over.
“Boxing us in” is the best verbiage for how I felt about that situation. It felt like being put in a cell, being told that it would expand, and then finding out that the expansion was really just a jack hammer for us to use to self-expand our cells using the internal tools inside of the cell. The cell can expand, but the expanded version will still be the cell, maybe a larger version, but still made of all the same pieces. No field trips outside, just more internal gears, turning in a machine that only connects to the world through a bland terminal.
As I progressed through academia, I embroiled myself further into this system of many parts and few connections. I did graduate research where the point was almost entirely to perform floating point math, obtain results, and publish about it. This system of code still had connection points to the external world, it just happened to be that the connection point was almost always the very developer who wrote the code in the first place.
Real Software is an Ecosystem, not a Species
Richard Dawkins writes great books, so good that they compel you to understand how evolution and biology actually works in the world. Some prerequisite work with definitions is important to get us started and all using the same language. Genes are the smallest meaningful chunk of evolutionary information. Genes affect phenotypes .Those phenotypes interact with the environment. Any coupling between the gene and the gene’s survivability from one generation to the next provides a mechanism for evolution to act. That coupling can only happen through
- firstly, expression in the phenotype, and
- secondly, the interaction of the phenotype and the environment.
These distinctions can be accepted as definitional.
The story gets weird when you realize just how complex the phenotype and environment system is. An “individual” is not present in the definition phase of evolutionary argument. Individuals are a derived concept, invented by evolution. Cooperation via kin-selection was the mechanism that allowed the emergence of communities of cells leading to individuals, and eventually even communities of individuals, symbiosis, and vastly complex networks of interactions.
Any realistic view of software in the modern world looks more like this view of ecosystems than what is still pitched in common intro to programming classes. The survival (or utility) of a program can not even be evaluated without the contextual information of the software forest in which it lives.
Isolation is a Feature, not an Assumption
Solving real problems in software development almost always entails a desire to use something outside the context in which the code is being ran (and beyond what it should have access to). It would be much easier to write model definitions if one could do unrestricted circular import. If a particular class from a particular module isn’t behaving nicely, it’s most tempting to directly modify it as-it-lays.
This is a familiar feeling for people who write software, and from it leads to a broad best-practice notion. A program that can be written to exist on its own without a-priori counting on a particular behavior of another part of the system is best. Many times this is possible, in which case we build a utility function that can be its own cul-de-sac within the code tree. However, for many components, this gets very very complicated as a project scales.
What is the Individual Anymore?
Evolutionary organization went through many phases, with each phase building on the last one. Cells took a long time to evolve in the first place, and clearly this was needed before multi-cellular life. Even within the cell, there were a great many innovations that needed to take place.
Right now, we may be living in the age of the “app”. We don’t know exactly where this fits into the larger architecture because, I believe, the complete ecosystems have not managed to find equilibrium. Interchangeability of apps is probably the primary software problem of our age, and it is what we will be remembered by. This strikes me as a study of the software “extended phenotype”, like that which occurs in evolution.
Programs, at the most basic level of organization, combine within the systems where they are placed to produce outcomes. Those outcomes are magnified through the mutual interactions of many apps in complex systems to produce higher-level combinatorial outcomes that are exceedingly non-trivial and difficult to predict strictly looking at the individual components.
If there is one prediction we can make from the evolutionary analog here, it is that the needed evolution can only take place after the systems are put into production, and when a proper process for reproducing, killing, modifying, and replacing the system components (the “apps”) can be instituted. Even doing so, it will take time and a great amount of external disruptions for it to reach equilibria which are radically productive.
by the author.