We move between the imaginary and the actual all the time in acting and in knowing, insofar as any knowing is already an acting. We do this in two main ways:
1. Taking the actual into the imagination as knowledge of it. Aristotle called this form of knowing episteme, and it is for most people what “knowing” primarily indicates. Insofar as the actual is determined in its having-been episteme is in an essential way oriented to the past-perfect, not the past as it was, which can only be virtual, but the past as it has been retained and therefore in a certain sense still is.
2. Realizing the imaginary and actualizing the imaginary real. Aristotle called this form of knowing techne. Most people consider the forms of techne as different types of doing, but just as knowing is already an acting, properly fulfilled doing is also a mode of knowing.
In software development, we deal with the line that separates the imaginary and the actual more closely than in most forms of techne, precisely because it is closer to the essence of techne as such than other forms of doing. To see how consider the following idealized model of the development of new software:
1. We begin with the pure imaginary, usually as a set of requirements. These may come from someone else or in the case of personal software development from ourselves, but the pure imaginary must be understood as the initial bounds (telos) of the imaginary real.
2. We may begin by creating an imaginary that realizes some of these bounds, i.e. a prototype, or we may begin by jumping straight in to the full imaginary real.
3. Either way, at some point the pure imaginary has to be sufficiently realized that it will work, at the moment it does work, i.e. the software is running, we have the actualized virtual, the software not as it is in code or diagrams but as it actually runs, which cannot be fully imagined nor viewed in the case of anything beyond truly simplistic software.
What has happened here? The line itself has become visible in a dual way, as the realized imaginary and the actualized virtual, yet these are in some sense the same. In a rough way, we can conceive them as the same in the sense that mind and brain are the same – they cannot encounter each other nor be separated, yet they are different – this difference is due to what we know as emergence. This double face is what every software developer must simultaneously see while fixing problems – debugging – the actualized virtual of the imaginary real.
Some problems exist in both, these are the easiest problems to debug and fix, and many common bugs fall into this category. The difficult ones, though, only exist in the actualized virtual yet must be fixed in the realized imaginary, the tangible codebase we are working on. This requires imaginatively projecting the actualized virtual as it must be in order for the observed behaviour to occur. Logging, monitoring and other forms of determining the state of the actualized virtual at given times attempt to help us accomplish this projection, but cannot do it for us.
The line which we are attempting to see both sides of at once by flitting back and forth is inherently the origin of stress and fatigue, and thus software development ranks among the most stressful and fatiguing jobs around, and the average career length of a developer remains shorter than that of a professional footballer. The higher animals must sleep, not crossing the line (hence dreaming) precisely because this crossing is fatiguing in a different way than physical fatigue.
Of course, non-developers also need to sleep, because in assessing the actual they must bring it across the line into the imagination – i.e. they must know it. In order to act they must imaginatively project the action realistically and then actualize it.
No matter how many times they cross the line though, most people do not abide with the line, which is the most difficult and fatiguing thing of all.
How can this be made easier? The most obvious way is to make the actualized virtual correspond to the realized imaginary as closely as possible. It’s for this reason that Smalltalk, for instance, is easier to debug than Java – there’s already a 1:1 correspondence between the code as written and as interpreted or compiled, thus removing one of the two places in which emergent behaviour can begin. It’s also the reason mainframe debugging is easier – the development and production environments are identical, thus emergent behaviour in the latter is more reproducible in the former.
The less obvious but necessary change is that we learn better how to projectively imagine the software as running rather than as static pieces of code.
Something else, perhaps even more important, has happened here. Most with a passing acquaintance with the works of Aristotle would say that the opposite of techne is phusis, not episteme, as I have claimed above. This is true, though, only if techne is seen purely as a doing and not as a knowing. Techne as a doing (making, fashioning) is obviously opposed to phusis (arising, emergence, growth). Yet the problem revealed here is precisely the operation of phusis in the core of one of the most technological of technical doings. The implications of this are too varied and complex to elaborate on in this context.