ACCU2016: Talk on Software Architecture Design 2: The Historical Context

[This is the second part of the transcript of my talk at ACCU2016 entitled: “Software Architecture: Living Structure, Art, or Just Hopeful Arrangements of Bytes“]

An enlightening aspect that surprisingly pertains to the issue of software design is the philosophical history that has led us to our current technological society.

Batalla_de_rocroi
Looking back we can see some origins in the Thirty Years War that took place between 1618 and 1648. Some commentators have drawn parallels with the impact of WW1 and WW2 between 1914 and 1945, saying that they could also be seen as a thirty year war. (See the book “Cosmopolis” by Steven Toulmin) The Thirty Years War of 1618 was a terrible war over much of Europe that resulted in the death of a third of the German population. It was a religious war between Protestants and Catholics, i.e. one religion – two factions – and raised serious concerns about the subjectivity of religious faith and the human condition. It was this that brought the quest for certainty to a head. The underlying question was: How can we be certain of what is happening in the world around us? And for the faithful in the 1600s, how can we be certain of God’s plan?

Descartes

It was during this time that René Descartes produced his “Discourse on Method” in 1637. He was the father of analytical geometry and of course coined the famous phrase “I think, therefore I am”. But this was predicated on the fact that we first doubt, thus the more correct phrase should be “I doubt, I think, therefore I am”. He concluded that because of our subjectivity, we cannot trust our senses and what they are telling us about the world, so he returned to the point of doubting. Since there was doubt, there must be a being that is doubting. This being, this ‘I’, that is doubting is thinking about this so therefore I am thinking. Since I am thinking I must exist in order to do that thinking.

Because the church was looking for certainty and because Descartes was able to couch his thought in terms that they could accept, this provided the foundation for the Scientific Revolution. This was followed by the Industrial Revolution which has led us to our current modern technological society. It is interesting to consider the fact that all that we take for granted today represents the end of 300 years or so of work based on Descartes’ philosophical premise: “I doubt, I think, therefore I am” where the aim was to try and eradicate subjectivity.

It is ironic that, although the aim was to be objective, his Cartesian coordinate system can be considered to be based on the structure of the human being! I stand up, and my head could be considered as the Y axis. I stretch my arms out to the side, there you have the X axis. I walk forward and there you have the Z axis.

This points to the difficulties that are implicit in the struggle to eradicate subjectivity – an objective (pun intended!) which I do not consider possible.

Kant

I usually refrain from mentioning Immanuel Kant since I am not a Kanitan scholar, but his thinking has formed much of the basis of modern thought. He produced the “Critique of Pure Reason” in 1781, and there is one quote I wish to highlight here from his considerable body of work. He said that “The world in itself is unknowable”. and this strengthened Descartes’ approach of not trusting our senses. It has given our modern scientific and technological society the excuse to allow our thinking to run ahead of the phenomena of the world.

This activity may sound familiar if you think back to the Path of the Programmer. It is a characteristic of the Journeyman phase.

With regard to my previous workshop on imagination, an area dealing with educating our subjectivity, it is interesting to see that one commentator, Mark Johnson, has noted that Kant had difficulty with imagination – Johnson states that he was “not able to find a unified theory of imagination in Kant’s writings” (The Body in the Mind p166).

Goethe

The third person I want to mention, and the one I feel most drawn to, is Goethe. It was Goethe who raised the warning flag to say that there was a problem with the underlying philosophy and practice of the scientific method. He pointed out that there was too much over-hypothesizing and that the thinking was going ahead of the phenomena of the world. Observation was not being given enough time.

This should ring alarm bells for any programmer because it is exactly what happens when someone takes an undisciplined approach to debugging.

Goethe, however, was particularly interested in understanding the growth of plant life. He wrote the Metamorphosis of Plants in 1788 and identified two very important activities. The first one is Delicate Empiricism (or “Zarte Empirie” in German), i.e. carefully collecting the data, carefully observing the world without overly disturbing its processes.

The second activity, which is what gave me the impetus to give my previous workshop on imagination in 2014, is Exact Sensorial Imagination. This is NOT fantasy, but exact, grounded imagination congruent with the observed phenomena. Goethe was trying to understand how plants grew and how their forms changed during growth.

For me this links to how software projects grow over time, as if they have a life of their own. A programmer needs to have a grasp of how the current software forms may change over time within such a context if they are to minimise future bugs.

The key difference between Descartes and Goethe is that Descartes was trying to eradicate subjectivity whereas Goethe was wanting to educate subjectivity.

The next important phase in philosophical thought is the advent of phenomenology in the 1900s. The realization that the process of coming to know something is crucial to, and as important as, the conclusion. Goethe is not considered a phenomenologist as he focused on specific phenomena rather than the philosophy behind what he was doing, but he definitely prefigured some of their ideas and so could be called a proto-phenomenologist.

We need to understand that phenomenology is a sea-change in philosophical thought. Here we are, living in a modern technological society based on 300 years of progress initiated by Descartes and his subject/object duality, and now the underlying foundational thinking has changed significantly.

The discipline of software development in the forefront of trying to understand what this change of thinking means in practice, though it may not have realised it. We need to understand how we develop our ideas and we need to understand our own cognitive biases, the subject of Dr. Marian Petre’s keynote “Balancing Bias in Software Development“. The point here is that we can do a certain amount in teams but there is also some personal work to do in understanding our own learning processes.

There is a wonderful quote by Jenny Quillien who has written a summary of Christopher Alexander’s Nature of Order books. She says in a preface:

“Wisdom tells us not to remain wedded to the products of thought but to court the process.”
(Jenny Quillien Delight’s Muse)

I think this is a lovely way of putting it. The process needs courting, it has to be done carefully as with Goethe’s Delicate Empiricism.

For those who wish to understand Goethe’s work and the philosophical issues around phenomenology, a primary source is Henri Bortoft. His writing is very understandable, particularly his book “Taking Appearance Seriously” and he draws on the work of Gadamer, one of the more recent phenomenologists.

ACCU2016: Talk on Software Architecture Design 3: The Issue of Doubt
ACCU2016: Talk on Software Architecture Design 1: The Path of the Programmer

Phenomenal Software: The Need for Exact Imagination

This is a crucial aspect of being a software developer – the ability to hold an exact imagination of the processes occurring within a system. Fundamentally whenever we have to debug or design a system we need to try and ‘run’ the system or subsystem within our own thinking, if only in part.

It is one thing to appreciate how the concept of ‘imagination’ can be used to describe this process, but it is another to truly understand the deeper aspects of the faculties we need to develop in order to perform this activity. In my experience most software folk have either developed some of these faculties unconsciously at school and/or university, usually by studying maths, or pick it up as they go along during their career – both frighteningly haphazard processes. We may need to include art training for the technical professions.

The Process of Goethean Science

My view is that the insights of Goethean scientific perception can help here, though there are some important differences due to dealing with dead machines instead of a living natural world.

First lets review current ideas about the steps that are used in Goethean scientific perception (See Wahl and Brook):
Created while on a painting course by Claire Warner.

  • Exact Sense Perception.
  • Exact Sensorial Imagination.
  • Beholding the Phenomenon.
  • Being One with the Object.

Usually these steps relate to the perception of natural phenomena rather than to software where we are dealing with human created entities running within a computer, but they are still relevant.

In computing the stage of Exact Sense Perception relates to either developing requirements (when designing) or observing the behaviour of the system (when debugging). I am not going to deal with this step in this post so that I can concentrate on the imagination stage. I will assume that either we have the requirements for a new piece of software, or we have followed the ideas in my previous post when investigating the behaviour of a faulty system that needs debugging.

In imagining these human created entities, or thought structures, we first need to duplicate them in our thinking. However, there is a state beforehand that is worth mentioning as in the above it has been accepted as a given. This is the step of ‘Developing a Focused Attention’ – which is a foundation for all that follows as I shall describe later.

Another point we need to deal with here is that when we work with these thought structures in our heads we have moved away from the sensible world and are using what Rudolf Steiner called sense-free thinking. Certainly we may aid our imagination by naming the structures after physical items, e.g. a pipeline, but we have also created new ideas, e.g. a FIFO [first in first out pipeline], that are not physically based at all. The entities we are dealing with are not sense-perceptible and are not physical items and so it is not accurate to call it Sensorial – a better name being Exact Sense-Free Imagination.

Thus I see the steps as follows:

  • Developing Focused Attention
  • Exact Sense Perception (not dealt with in this post)
  • Exact Sense-Free Imagination
  • Beholding the Phenomenon
  • Being One with the Object

Developing Focused Attention

K13 Approach
In the past this would not have needed mentioning but given modern issues of reduced attention spans it needs to be brought to awareness. I consider this to be the most important faculty I have developed over the 30 years of my career in a technical domain and it is very relevant to life in general. When a software problem is found by a customer it can result in them being quite vocal and upset and getting angry – an appropriate response if they have paid for the system.

This heated response and emotionality can ripple through the vendor company as the customer interacts with its various levels of sales, support and management. If the emotionality persists all the way to the level of the programmers, it is going to be impossible to cleanly fix the problem and will result in a lot of costly, ineffectual ‘thrashing’. This is because in order to properly imagine the system in their thinking, the programmer must hold a focused and clear attention. In effect they have to push the worries of the day-to-day economic world away while they calmly and quietly identify and then fix the fault, possibly educating the various stakeholders about what they are doing in order to gain a little quiet space and time.

Although the customer may be getting ‘appropriately’ angry, ideally this attitude of calmness needs to be developed by all members of any technologically dependent society. Otherwise we will experience a degradation in the quality of our lives as we persist in holding expectations that are not in touch with reality. We need to become more aware about the implicit issues of technological use as it amplifies our intent, including our mistakes. This is where an aggressively economic stance can adversely affect our lives and thinking.

This stage of focused attention requires that we develop our ‘Will’ in the realm of our thinking. We will not make progress by letting our attention wander and our thoughts flit around like moths near a flame. This use of willpower is one of the reasons that the practice of software development is so draining and I liken this to creating and holding a quiet, almost physical, space in my mind in which to run the system in my thinking. (Those of a more spiritual/religious nature might see this as a sacred space, like that of a church, grail, or sanctuary.)

Exact Sense-Free Imagination

BufferThe current prevailing view is that when we are imagining a system in our thinking we are using a visual metaphor. This idea has been furthered by the move from procedural programming to object-oriented programming back in the 80s [See footnote 1]. This assumption has also been consolidated by the discipline making use of the idea of patterns put forward by Christopher Alexander [See footnote 2]. The architectural patterns for buildings indeed are visual entities, but when it comes to imagining the interactions of software structures it is more complicated. (You might actually say the same about building architecture but that is another discussion.)

There are two main aspects to what we have to imagine, first there are STATIC structures, and secondly there are DYNAMIC operations that occur between these structures.

Imagining the static element is when we build the system, usually only partially, in our thoughts first. Here ‘Thought’ is the noun use of the word, and is as close as we come to a visual representation of the code since we usually create a structure of ‘Thoughts’ out of the data structures or objects (if we are using object-oriented programming).

This means that we are imagining sense-free thought structures in the quiet space we have created with our focused attention.

Next is the harder aspect of imagining the dynamic operation of the system. The computer will perform operations exactly in line with the software we are about to write (design) or that we have already written (debugging). When designing we need to imagine if our proposed structure is going to give the required result for the specification drawn up for the system. When debugging we need to imagine what the system is doing and why it is not performing as we expect given our knowledge of the code.

In both these scenarios, as we think through either reproducing the static structures or the activity of the system we need to incrementally move our imagination forward in steps to be sure it is congruent with the code or proposed coding ideas. This, thanks to the operation of the computer, is why this process must be an ‘Exact’, non-fantasy imagination.

A frequent error here is to ‘run ahead’ of the simulation in our heads, missing out vital steps – so we need to start small and will usually use paper and diagrams to help us along. Interestingly I have found a printing whiteboard to be invaluable as the gross motor movement in drawing a structure diagram in the large helps to improve the visualisations of the thought processes and imaginations (schemata as Johnson says in The Body in the Mind).

However the fact that we perform this imagining of the dynamic system state, along with my own experience of the process (many programmers will ‘see’ the code in their mind’s eye), makes me sceptical that we are dealing with a purely image based and visual domain here. This is a current work-in-progress for me at the moment.

Note how this need to NOT run ahead of the simulation echoes the idea of Delicate Empiricism – which leads us neatly onto the next stage of ‘Beholding the Phenomenon’.

Beholding the Phenomenon

This is where we actively perceive the behaviour of our (hopefully exact) imaginations and necessitates switching constantly between imaginer/creator and perceiver. I find that nowadays I do this without noticing the switching, but it takes a significant amount of energy as this is another activity that requires a lot of willpower.

I am having to use my Will to:

  • Maintain focused attention.
  • Create thought structures.
  • Move my imagination through time as I simulate their interactions.
  • Behold what is happening and compare with the requirements.

The best way I can describe the feeling here is that of using a lot of attention to just hold the structures and keep the dynamics ‘alive’ and wait for the perception to catch up. This is why I consider that the word ‘beholding’ is a good way to describe it because we need to balance letting the imagination ‘live’ along with keeping it ‘Exact’.

There is also a very delicate, sensitive ‘cognitive feeling’ going on here when designing and comparing to the requirements as I assess if I am creating the right structures. I will return to this idea in a later post as it relates to Christopher Alexander’s work.

Hopefully this makes it easier to understand why programmers frequently get that far away look in their eyes. Given the complexity of what is happening is it any wonder that bugs occur in our creations?

Being One with the Object

Although difficult to reconcile with the perception of the wholeness of a natural organism, by thinking of this as a creation of knowledge, understanding and meaning, we can make the link. This is the ‘Aha!’ experience and is just as relevant in computing as in traditional science, Goethean or otherwise.

Gliding Sunset

This is the moment when we bring life to the whole enterprise, using our uniquely human faculties.

In a computing context this means that either we have truly understood the detailed elements of the problem and have identified the structures we will need (design), or we have experienced the blinding clarity of seeing exactly where the problem lies (grokking it) and know what we need to do to fix it (debugging).

Health Warnings

crash2
When working with computers we need to realize how it can fossilize our thinking. Because we constrain our inner process to be in step with the machine, we can delude ourselves into thinking that we are just machines. Indeed we may even change our judgement to be far too rule-based, the essence of computer operation.

We need to hold onto the idea of a ‘Living Thinking’ (as Steiner would call it) and I find that the phenomenological ideas of Goethe and those that followed can help us in keeping this uniquely human perspective when dealing with the mechanized world.

Next…

Next time I shall go more into the ideas of patterns, Alexander’s ‘apparent liking’ and ‘true liking’, and the idea of how we use a very fine ‘cognitive feeling’ to judge the rightness of a design.

Footnotes
[1] This was a major change in the way humans thought about programming computers. Initial techniques involved stringing together sequences of machine instructions into procedures that manipulated data, hence the term procedural programming. However it was then decided that it would be a better to give the data structures primacy and attach the procedures to the data. Thus software development became based upon designing structures of objects (or more accurately: instantiations of abstract data types) i.e. data structures with ‘attached’ procedures. Thus was born the idea that you could visually represent software structures which would make it all much easier to imagine.
[2] Christopher Alexander is a mathematician turned architect. The software discipline has used this idea to provide design patterns for software structures. His magnum opus is the 4 book sequence called ‘The Nature of Order‘.

Phenomenal Software Development : Delicate Empiricism in Software Development

I am going to start this section with a discussion about doubt, or unknowing. This was not in the original talk since it would not fit within the time allocated, but the response I received when I included it in a subsequent version of the talk makes me realise that it is a key idea we need to consider.

CloudscapeThe Place of Doubt or Unknowing

If we take the Cartesian view that we cannot really know the ‘things in themselves’, then in terms of creating new knowledge we have two possibilities:

  • Run Away
    We can decide that since we cannot get to know the Things, then we should not even try. This is the path chosen by those that wish to shun everything technological and go back to the old pre-modern ways. But as Ken Wilber points out in The Marriage of Sense & Soul(p44), I don’t think many folk today would want to go back there if they really knew what it was like.
  • Over-Hypothesize
    Here we decide that we can be ‘Aggressively Empirical’. Don’t waste too much time with observation, just come up with hypotheses and test these against reality. This approach has no consideration for the embeddedness of the perceiver within the system being perceived, the classic dualistic bind, and can lead to an experiment reinforcing your expectations about a phenomenon.

Note that both of these approaches attempt to push the unknowing away.

Unknowing does not feel comfortable so a typical human reaction is to move away from the discomfort. But in this area it is a mistake. So what can we do?

  • We need to develop ourselves and stay with the unknowing. This is the Delicately Empirical approach. We should consciously stay with the doubt and keep observing, hold back assumptions until our ideas and thinking mature in line with our observations.

It is this latter approach that requires a stronger sense of self in order to stay longer with the unknowing and the ability to hold this state is a core skill when working in a technical environment.

ThermallingKnowledge or Preconceptions?

The first point at which I got an inkling that the field of software development could benefit from the insights of Delicate Empiricism was during a workshop at the OT2001 conference when I attended a session called “Tracer Bullets” hosted by Paul Simmons and Tom Ayerst. They initially showed a short film about the difference between the Russian and American approaches during the space race of the 1960s. The Russians were much more trial-and-error based whereas the Americans had a very strong quality assurance programme. [I notice there was a re-imagining of the session at SPA2013]

The workshop part of the session involved splitting up into small teams of about 4 or 5 people. Each team had a range of materials they could use to try and identify what item was hidden within a tall kitchen bin placed on a stool so you could not look down into it. Each team had to create tools to find out what was at the bottom of the bin. There was a limitation in that each team only had 8 tokens which would allow them to go up to the bin for 1 minute per token. So they only had 8 minutes of ‘research’ time up at the bin.

Having already been familiar with Goethe’s approach of Delicate Empiricism, I argued in my team to use the tokens one at a time and only go forward slowly. Luckily the other folks agreed with the approach and we set off. What surprised me, and provided the impetus for this research into phenomenology, was seeing the approaches taken by the other teams. Whereas our team simply went up with some long balsa wood ‘pokers’ and spent our first minute just stabbing around to get an initial sense of what was at the bottom of the bin, I saw other teams creating elaborate measuring tools which already pre-supposed certain attributes about what they expected to find. A classic case of over-hypothesizing.

Before using each token our team decided to identify what it was that we wanted to learn next, i.e being clear about the boundary of our knowledge, and devising a tool to move that boundary forward. Then once we got the extra data, we would reflect on it and adjust the model of what we thought was at the bottom of the bin. Then we would discuss what it was we wanted to know next, making sure that our hypothesizing did not rush too far ahead of our current knowledge.

My observation of this contrast between our approach and that of the other teams gave me the impetus to delve further into this subject.

The primary question to ask here is just how aware we are about our boundaries of knowledge, and do we know how best we should proceed when at those boundaries? These questions are absolutely crucial when it comes to debugging a wayward software application.

From the workshop I identified the following steps in the process:

  1. Ask: What do we already know?
    We need to be clear about the knowledge we already have and need to consciously check the limits of that knowledge. This knowledge then forms the foundation for expanding what we know. In certain cases we might decide that we need to move into learning about a completely different area.
  2. Ask: What raw data do we need next?
    What is the next piece of raw data we need to help us expand our knowledge? Note that I differentiate here between raw data and knowledge. The raw data we collect relates to the percept. It will need our reflection to find what concept fits the data. Done properly this enables us to create a mental model that properly fits the phenomenon and is not abstract.
  3. Ask: What tool do we need to get this information without overly disturbing the phenomenon?
    Here we need to focus on creating the best tool for the job of finding the next piece of information we need, but without disturbing the system. This latter consideration is particularly important when debugging real-time multi-threaded systems. I find I frequently fall back into the ‘old school’ tradition of printing out the data if I can because usually a debugger is too invasive. (see ‘Staying Free’ below)
  4. Research: Use the tool to run the experiment and collect the raw data.
    So at last we get to do what feels like ‘real’ research. In actuality the ‘real’ research starts with our thinking. Frequently programmers love to get to the keyboard too early because they (and their managers) mistake typing for software development. It feels safer because one feels like one is making demonstrable progress. But this is an illusion and is at the core of Robert Glass’ fact about the ‘disconnect’ between management and programmers. In arguing this I have found David Bohm’s insight that the experiment is purely an external manifestation of the thought concept useful.
  5. Reflect: Expand my knowledge by reflecting on the collected data.
    This is where we need to look at the data we have collected (the percept) and start developing concepts that match it. By using a disciplined imagination we can check our concepts against the data and when we match them (the Aha! experience) we have expanded our knowledge. So now we can go back to stage 1.

Crash1Staying free – Knowing your technology

As mentioned above programmers will likely use debuggers for helping them investigate a problem. This can work well when you are trying to find a fault that is relatively easy to pin down. This is because a debugger will have to modify the running code in order for it to be able to function. For instance it may allow the program to stop at user specified points which it can only do if it modifies the running software. It may also completely modify the memory footprint by putting guard areas around the ‘real’ areas of data in order to catch ‘illegal’ memory accesses outside of what was expected.

Now that systems and debuggers have become more complicated, it is not a given that a programmer will know what the system is doing underneath the hood to provide this helpful functionality. This is where we touch on the nature of freedom. If you do not know what the system is doing – you cannot be free, i.e. you cannot know exactly what is going on, and so your assumptions can be faulty. I will come back to this concept in a later post since it relates to ANY technological use and should start some alarm bells ringing.

But back to the developer. As you can imagine, if you are working on a system that has real-time constraints (I work on video systems which need to play out faultlessly for hours) it just is not feasible to use a debugger to help find some of the nastier problems. Hence my comments above about the ‘old school’ techniques, i.e. printing out the data. With older systems it was not even possible to do this without disturbing the real-time operation because the process was too slow. Nowadays you can generally get away with it, but there will still be the occasional problem where printing out a single number could cause a change to the timing of the system and thus the fault will not manifest. Thus you need to know your system and then know what is the best ‘instrument’ – code modification – that can collect the data you need to find the fault.

Computer as Thought Mirror

Pity the novice or  journeyman programmer who has not yet realised that his or her process of debugging is flawed. All too frequently I see less experienced programmers (a) jumping to an early conclusion about the cause of a fault and then (b) modifying the code to ‘fix’ the problem based on this conclusion. Jumping to the wrong conclusion too early happens time and time again and you will see it happening many times a day in most software companies.

It can cost them a lot of money because they may now ship this software proudly announcing the fix of this specific bug only to find that it has re-appeared in a slightly different guise. What has usually happened is that the timing of the system was changed so the original fault became hidden, but the actual cause, i.e. the bug, was still there. I have found from bitter experience that it can take many many years – a decade is usual – for a programmer to sufficiently hone their debugging skills to the point that they do not fall into the trap of making false assumptions. It truly requires a great deal of willpower and self-awareness. Of course, better processes can help but they will still rely upon discerning human judgement.

The developer is having to learn the boundaries of their knowledge the hard way and the computer is mirroring back the quality of their thought process. Hence my calling it a ‘Thought Mirror’. Generally the novice starts out having great faith in their ability to understand the effects of their software creation, possibly being surprised that it is going wrong. If they are truly growing through the course of their career this will change to assuming they are wrong and possibly not even trusting that the code is correct even though the system is functioning perfectly. You will also find that many seasoned programmers will not buy the latest and greatest software releases – unless they really really have to!

I hope that gives you some sense of how convinced I am that anyone good at debugging will be using the technique of Goethe’s Delicate Empiricism without even realizing it.

Have we unconsciously created a technology that pushes us to the limits of knowledge just so we can come to know ourselves better?

To paraphrase Jeff Carreira, in software development ‘philosophy is not a luxury’.

Next time I shall take a deeper look at the issue of disciplined imagination, Exact Sensorial Imagination to be precise, and how it relates to software development.