Cognitive Psychology and Program Debugging
Cognitive Psychology is a well-developed field. With few exceptions, there seems to be little overlap between the study of Cognitive Psychology and the practice of program debugging. However, the study of mental models is one of the central themes in Cognitive Psychology (Lindsay and Norman, [LN72], devote a significant percentage of their book to the issues of forming cognitive models; the massive work by Newell and Simon [NS72] similarly concentrates entirely on how we form mental models.)
Some assumptions become clear after we distill the work of the cognitive psychologists:
- When working in a problem domain, the closer the problem domain corresponds to our mental models the more effectively we can deal with it.
- An optimum arrangement, which we attempt to achieve during problem solving, is to cluster the concepts of the problem into groups that we can manage as groups rather than as individual components.
Now compare this with our software models:
- We build our software by using objects which represent our mental model of the problem decomposition.
- When debugging, we try to apply our mental model to the perceived problem.
- An optimum arrangement is when the system we are analyzing can express itself in a format compatible with our mental model, including semantic grouping.
The object methodology in fact attempts to achieve these goals. Thus, the software objects achieve a mental persistence, within our mental framework when the objects we are debugging and the objects of our model correspond. But now look at how we usually debug:
- We set breakpoints and examine variables and execution flow. We work at an implementation level far below the object level we coded at.
- By studying these variables and execution flow events, we attempt to infer if the dynamic behavior corresponds to our mental model, by a complex process of mapping our mental model to bits, bytes, and program counter values and attempting to deduce if these actually fit the model. We do this by mapping the bits, bytes, and program counter back into an object model, and look for where our inferred object model differs from our presumed object model.
- Because the format in which the problem is expressed is incompatible with our mental model, we are working at a significant disadvantage.
One example of how we use our mental models is our tendency, as programmers, to anthropomorphize our software objects, and to refer to them as if they were intelligent agents acting on our behalf. This tells us how our mental models work. Even before the days of object-oriented methodology, we had a tendency to treat components of code as objects. But when it comes to doing the design recovery that we need to do in order to debug, we find that we have to keep reconstructing mental models, building and testing hypotheses, and trying to reconcile a high-level mental model with an idiosyncratic representation, the above-mentioned representation of bits, bytes and detailed control flow.
What we need here is software that does not just present us with state to examine, but actually works in a proactive manner to exploit our perceptual systems and maximize our ability to reconstruct these models or test these hypotheses. A debugger that more closely represents its information as objects and gives us insight into the object methods and states is better than one that works at the bits-bytes-program counter level.