Programs Represent Mental Models

Good programs contain clear representations of mental models. This statement is obviously true, but so much can be reasonably said about it that it is hard to know where to start.

First the basics of why it is true. Any program is a textual representation of how the programmer thinks the program is supposed to work. It contains instructions for the computer. It also contains signs and hints of the programmer's thinking. In the case of a good program the programmer has a clear concept of how the program is supposed to work, has represented it well, and has tried to make it easy for the maintenance programmer to maintain that conceptual clarity as the program's behaviour changes. Conceptual clarity is a sign of a good mental model. Therefore the program ideally contains clear representations of these mental models.

PeterNaur has an excellent essay on this topic called ProgrammingAsTheoryBuilding. It can be found, among other places, as an appendix to AlistairCockburn's AgileSoftwareDevelopment. It talks about the phenomena of programs with clear theories. For those with the theory, the documentation and source are both crystal clear, the possessor of the theory has no problem figuring out what the program should do and then pointing you at exactly why it should do that. To people who do not understand the program, it is as clear as mud, and the things that they think are improvements quickly will turn it into a mess. (I think most of us have seen examples.)

Hopefully you are convinced. So what does it tie into?

The answer is a lot. The main thing that it says is that a primary activity of programmers is the formulation and communication of these mental models. GoodVariableNames communicate volumes about how we are thinking. Documentation and comments are supposed to (but may mislead). We like ObjectOrientedProgramming because it provides constructs to assist in making the components of our models clear. A clear SystemMetaphor is good because it guides your mental models. DesignPatterns provide a set of shared constructs that programmers can use to make models easy to pick up. Even a low-level book like CodeComplete ties back to this principle when it tells you that, The more you make the program read like a solution to the real-world problem and the less like a collection of programming-language construct, the better the program will be. What is that saying? It is saying that you should first implement the necessary pieces to speak in terms of the program domain, and then speak in that domain-specific language. Those pieces are, of course, your theory of the program domain made concrete! (OnLisp has much to say about this strategy.)

Of course the explicit observation that a primary activity of programmers is the formulation and communication of these mental models makes it easier for us to focus on actually doing that. This is useful information. We would do it anyways, but mainly by accident while doing other things. When we know that it is an important activity we know to pay attention to the ConvectionCurrentsOfInformation. What you really want to document is whatever will make it easier for others to pick up those mental models. If a shared joke does it, than that joke is more important than official technical blather.

Going in a different direction, this tells us that good programs look like good mental models. What do good mental models look like? Well according to our understanding of human cognition, good mental models are very good compression algorithms for their subject domain. This has easily verifiable effects. For instance expert chess players have been found to have little or no advantage over non-players at memorizing random arrangements of a chessboard. That has nothing to do with playing chess. But they are far more able to memorize the arrangements of pieces that show up in real games. Similarly you can much more easily memorize something written in a language that you know than you can something written in a language that you don't. You literally can process the phrase through your mental model of the language you know and wind up with a much smaller thing to remember, which is then much easier to remember. And - very characteristically - your errors in the language that you know do not tend to affect the "meaning" of the phrase, while your mistakes in the other do not make sense to others. (I cannot resist a link to about dreams and learning, even though it is only somewhat related.)

So what should we predict about about good programs if they build up and then represent the world according to a good mental model and mental models are good compression algorithms? What we should predict is that they are remarkably short for what they do. We should predict that there is very good return on information transmitted per effort spent reading. More than that, we should predict that the amount of information transmitted per amount read should be relatively independent of what part of the program we look at. (Some parts cary information about the whole program, some information about minor details. The two are equal in InformationTheory, though we attach different amounts of importance to them.) We should expect a fair amount of uniformity in the layout of the code.

These are non-trivial predictions. Do they match your experience?

-- BenTilly

This supports my idea that Programming is more Art than Science. :-)

-- WadeBowmer?

You may find the program comprehension research area of interest, which deals with the building mental models of the underlying software at various abstraction levels, ranging from models of the code itself to ones of the underlying application domain. See the ProgramTransformationWiki, in particular

for more info.

The relationship between mental model construction and some of the ExtremeProgrammingPractices (such as UnitTesting, PairProgramming, and ReFactoring) is covered in my paper -- ArieVanDeursen, Jan 2003.

View edit of December 5, 2003 or FindPage with title or text search