Computer programs as systems
Program::system ("systemic" like OS or DBMS, **software application/application)**in the process of their operation--this is a thing, a physical object, it occupies a place in space-time, it is material. You can "tap" on a running program (a part of the computer that changes its state during program operation), you can poke it with your finger. A running program is a physical part of the computer that performs calculations of this program during its operation. The program is described by its algorithm (description of the calculation sequence), documented in the form of program code in some language (machine code in computer memory at the time of program execution, programming language during program writing). But the algorithm does not change its state when it is "working" because it is just a description. However, the computer that interprets the algorithm changes its state during the execution of this algorithm--both the part that is executing the algorithm and is the program::system. Dijkstra defines a program as: "program = algorithm + data structures". Structured data change their state during the execution of the program. The algorithm can also change during the execution of the program (a part of the algorithm can calculate another part of the algorithm as its data, and then this other part of the algorithm will also be computed). In any case, a program (algorithm and data in memory, "animated" by a processor -if we are talking about classical computer architecture, but there may be cases where the processor and memory are not clearly separable) during its operation--is an object that changes its states and thereby behaves in some way, it is an object of four-dimensional space-time, it can be considered a system.
A program as a physical object during operation has different states, which are physical states of RAM and CPU registers, reflecting the current state of the algorithm and changing data developed during program execution. The computer is engaged in physical processes/changes/interactions of its constituent parts (memory, CPU) during data computation according to the algorithm as a description of the program. These processes in the computer occupy some place in physical world: space where interacting computer parts are located, and time during which the program (part of the computer) performs calculations.
Once again, it should be emphasized: the program should be considered as a system only at the moment when it is actually launched and running, doing what it was written for. This is quite counterintuitive, but the source code of the program-- this is not the program (algorithm and its data), but only a description of the program; the source codeof the program in version control systems or in a file on a storage medium-- this is only the documentation of the program. There are also data that the program will receive after it starts working and will output after it finishes work. Do not confuse "description on a storage medium," a photograph of a person with the person himself. The program-- that which reflects the state of data at the moment of its execution, that which changes its states during the execution time (not at the time of creation). The source code does not change its states during execution, there are no changing data, it is just a description of the algorithm and data structures.
Therefore, programmers who believe that their engineering work is complete at the moment of writing the source code (algorithm and data structures)--these programmers are deeply wrong, and this is a common mistake. The recognition of this error has led to the emergence of entire movements such as DevOps[1], SRE[2] and platform engineering[3]--the programmers have recognized that they must be concerned not only with coding the program as the algorithm and data structures (development time Development), but also with running it on servers (operational time Operations). More details on this will be covered in the course "System Engineering."
The source code--is a description of the program (it is done "in classes", like any other design, one source code describes multiple possible instances of the program). Before using or operating the program, it must be manufactured using the source code as a "description with sufficient detail for production": it is compiled, assembled, placed in the memory of the required computer (possibly, before that put in some container) and started. Nowadays, the source code in language becomes an internal representation: the description of the program is done in natural language, then the program text is written and handed over to be executed by an AI agent, most often referred to as Copilot. We are not focusing on these specifics of making a program from descriptions. What is more important is the differentiation between
- source code::description of the program (algorithm and data structures),
- File::document with a description of the program ("informational object"),
- running program::system.
Therefore, the program as a system leads the process of changing not only its own states, but also the states of the environment (for example, input-output devices), performing operations on data stored on the computer as a data carrier/computer. We are interested in the process of the program::system execution as the behavior of this system on a working instance of computer(s) (for example, client and cloud), at the moment when a part of this computer (or computers) acts as a program, changing the physical state of the parts concerned (locations in space-time), which are repositories of information about the program algorithm and data. It is clear that from the source code to a running program, there is usually a long path, which used to be mostly covered manually by programmers and computer operators, and today is mostly automated by the computers themselves.
The error that programmers make by considering their source code as the program itself is the same kind of error that designers make by considering their information models (or drawings) as the system they are creating. A map is not the territory, a menu is not the meal, and drawings do not fly; the source code does not retain the values of its variables (damageable data) during execution[4].
So, the first mistake is to consider that the source code of the program is the program itself. No! The source code--is a description of the program!
The second mistake is to consider the program::system (even without confusing it with the source code) as the system to be created and maintained. If you ask a program developer what system they are building with their colleagues, the typical answer would be "my target system is the program." This is an error: considering the program as the main system when the program only contains a description of the target system in its data (for example, it is part of a control system/digital twin, having no separate meaning apart from the controlled system/physical twin). For example, we have already considered that an ERP system as a program contains a description of the flow of components through the enterprise in its data, it is needed only to manage this flow in some way, to optimize it.
As soon as a developer forgets that their program is just a digital twin of a physical twin, and that they are developing a whole system from the digital and physical twins, the project will fail. It is like a plane designer not being interested in the whole aircraft, but only in its control system. No, the reliability of the ERP system is not determined by its own operation, but by how it manages the flow of components through the enterprise, focusing on the behavior of the physical twin. The reliability of the aircraft's control system (digital twin) is not self-determined but by the aircraft's flight (the physical twin). Important is the behavior of the physical twin, and the creation and development of a system from the subsystems of the digital and physical twin. Even in weaker versions of the digital shadow and the digital model, this principle applies: the digital twin--is an automatic control system, the digital shadow--is an automated control system--it receives data from sensors of the physical twin, but only displays the state to the operator, and they then control the system by hand. The digital model receives data "manually" and provides control parameters for "manual" operation. For example, a car navigator with an autopilot--is a digital twin, the navigator with satellite sensor indicating where to steer--is a digital shadow, and if the navigator has to provide directions on where you are and then guide you on where to go--that is a digital model. Talking about software today should be done considering that this software is either an agent itself, a digital twin, a digital shadow, or a digital model of some other system--a physical twin (or software--part of a network of software, digital twin network--and we need to think about the physical twin that is operated by this network of software).
The third mistake "the program as the system we develop"-- is to consider the programas the developed system, not just as a subsystem, especially when dealing with supporting the work of some org unit with people or other programs. If your payroll program works perfectly, but you forgot to train the company employees or AI agents (or even other automation programs) on how to operate the program, it means that the program is not functioning: the payroll is not being issued! If payment is only "for the program," then there can be endless arguments afterwards about who will pay for employee training or AI agent training, or who will pay for reprogramming all related programs (which may cost much more than developing the discussed payroll program).
In the case of the digital twin error, the program and its data (e.g., in databases) are understood as a book: most people are often more concerned not with the book itself, or even with the content of the book (the book's text), but with the worlds described in the book. With software, it is the same: people are usually more interested in the described fragment of the surrounding world than the program itself (not more than the book and its text). If you have a dry cleaning order program, you are interested in getting your clothes clean, the money being deducted, transportation options for the clothes to and from the cleaning service. The program is of interest to the programmer, but it is their personal matter; everyone else is concerned about how the program will handle the dry cleaning situation, and it should concern the programmer too. If the program turns out to be excellent as software, but the dry cleaning cannot be done with it--then the project is a failure! Software is cunning: if it is perceived as the target system, it usually works with descriptions of the target systems, look behind them for the physical world where changes matter!
In the case of the error "our responsibility is only for the program, we know nothing about people and the organization," only the software is included in the target (or even "our") system, not the service provider/service provider that performs a meaningful service (operations that change something outside the service), supported with software. In corporate software development, customers expect at the end of the development not just a correctly functioning computer with the application::program, but a correctly functioning part of the organization, which the computer should support: people in the organization must work together with the program following an organizational algorithm, a "workflow," executing the work procedure that considers the program usage-- meaning, they need to demonstrate "mastery"-- analogous to the program: **. Software does not work without people; the software must be presented working with people (although more and more often people are being replaced by other software, including AI), but eventually the control is not on the execution of the states of the program itself (program behavior), but on the change of states of something outside the program.
Such joint human and computer service is usually called a workflow ("work procedure"::behavior), but it is also frequently referred to as an "org process," and a "workflow process," not focusing on the actual instances of work but on the method/way of work, including the program's operations in the common operations of an org process. The program-in-development is usually just a part of the target org process-in-development. Delivering a working program will not succeed alone; its work is not needed by anyone. What is needed is the org process-in-operation, where the program is only a part, alongside other programs, people, and sometimes other equipment, and they all must collaborate correctly. If the "order application of dry cleaning" works, but no one knows how to use the program, then payment for the program's work won't be made. Payment will be made for the business trips that will only happen when people and the "order application of dry cleaning" work together. Payment for the functioning of the dry cleaning program will not be made! Software is usually just a part of the system that is created and developed as part of a software development project!
Processes (including org processes, work processes) are challenging for people to think about. Hence, the program here would be part of the org unit (division, project working group, service, service provider), which will make the required changes ultimately (through chains of multiple changes of descriptions and descriptions of descriptions) in the physical world. The program itself is only a personal matter of the programmer or a small team of programmers, keeping it at the center of attention as a full embodiment of some target system--is reckless; it is typically part of a larger system, like an engine in an electric car or a washing machine control system. The engine--is a critical part of an electric car, but what is usually needed is not the engine but the electric car. If the motor works excellently in the electric car, but the car won't move because the engine does not synchronize well with its design, no one will pay for the engine, payment will only be made for the operational electric car as a whole. The same is valid for a washing machine control system: what is needed is not the control system itself, but the working washing machine--developers will be paid for that, and developers of the control system will get only a part of that payment as long as they successfully manage the washing machine, not to the extent the control system works only by itself.
The complexity further arises because software/programs/applications as informational objects (data carriers with descriptions of algorithms and data in databases) can build long chains, where based on some program descriptions (or even departmental programs-with-people) change other descriptions, then more, and only at the end of that long chain of "described descriptions" does the desired change in the external physical world occur. You may spend a long time describing where to get money, your intentions, recording the results of decision-making taken by many other tools and people into the computer and/or phone, but only at the end of the long chain of booking flights and checking tickets, as well as verifying the plane's presence at the parking slot, will you be physically allowed onto the flight: hundreds of varied software applications and people, some of whom you know, some you don't, must act to achieve the state "I boarded a flight ready to travel" in the physical world. If this final condition is not met, all these programs and people have worked in vain. So do not hesitate to "unwind all these" "description of descriptions," all those long chains of programs and programs-with-people, until you reach changes in the physical world for which the whole process is designed. And make sure everything is in order in the physical world. Yes, it's challenging, but system thinking requires you to turn your attention in that direction. It's vital: shifting discussions of software operation to discussions of changes in the physical world-- this is relevant; if you lack reliable and anticipated changes in the physical world, there is no need to develop a software project; after all, nothing will change in the physical world!
For example, this connection between software objects and the physical world is discussed in the domain-driven design approach (DDD), where it is required that the program objects directly reflect the objects in the physical world in the company's working domain (however, there should also be reflection of the objects in the mental world--the description world--though that is not essential for us at the moment)[5].
https://en.wikipedia.org/wiki/DevOps, there is a similar version of this movement, SRE, and a more modern variation, platform engineering ↩︎
https://en.wikipedia.org/wiki/Site_Reliability_Engineering ↩︎
https://platformengineering.org/blog/what-is-platform-engineering, https://thenewstack.io/how-is-platform-engineering-different-from-devops-and-sre/ ↩︎
There is a nuance here related to von Neumann architecture: a program can be considered both as data storage and as an executable object. The same applies to the "program in the brain": whether the neurons in the brain contain only descriptions, or whether the neural network is currently "calculating" something, i.e., a program-as-a-process in the physical world--this is the same question about the "materiality of thought." These are nuances that we are not discussing here. The advice here is to assess the likelihood of whether we are talking about a "simply documented description of a program/thought" or an "executing program/thinking thought," and base this assessment not on "truth," but on the goals of a particular action. It is necessary to discuss the most likely situation, relevant for achieving the intended purpose. However, this nuance is not essential in most situations. We remember that in systems thinking, we are not dealing with pure mathematics with 100% formal statements that cannot always be applied to real life, but with probabilistic reasoning, "as in life." ↩︎