Summary of "Programming as Theory Building"
Posted by Al Sweigart in misc
Peter Naur (of Bauckus-Naur form fame) wrote an essay, Programming as Theory Building in 1985 that explained what it is that programmers do when they are programming. In this article, I discuss and summarize the essay. You can read the full essay online, but the short of it is:
- Programming is not an assemblyline task that can be done by interchangeable programmers.
- Programming is not just the act of typing code.
- Software is not a product that can be measured in some straightforward unit of software output.
- Programming is not a direct, rule-based process that produces software the way following a recipe produces a cake.
The programmer has an understanding of the real-world problem and how the software they create solves this problem. This understanding is called a "theory" in the Gilbert Ryle sense where it means a conceptualization or mental model or systemic explanatory framework. A lot of the programmer's theory isn't captured by documentation, and if new programmers are brought in to modify the code, they'll likely make basic mistakes and misunderstandings since they don't have the theory of the "why" behind the design of the software. Naur calls this the Theory Building View.
Additionally, I'm interested in how this 1985 essay compares with AI-generated code, especially "vibe coding" done by non-software developers. In this post I'll use "vibe coder" to mean non-programmers familiar with using computers but uses an LLM to generate software. I also talk about the promise and utter failure of AI "expert systems" in the 70s and 80s to replace human programmers, and how this should be kept in mind given that Naur's essay was written in the 80s.
I'll go through each of the sections of the essay in turn.
Programming and the Programmers' Knowledge
Naur explains that programming should be seen as the building up of a theory behind a program; the theory is an understanding of why the program is designed the way it is and how it solves a real world problem. This theory exists in the mind of the programmer or programmers and is immediately accessible, while written documentation is an auxiliary, secondary product of developing the theory and source code.
Naur presents two anecdotal cases to back this up, communicated to him by first hand accounts. Case 1 is a compiler programmed by group A which is then later expanded upon by programmers in a separate organization, group B. The B programmers, not having developed the software or the theory behind it, made suggestions for changes that didn't take advantage of existing features of the compiler. The A programmers could immediately offer advice on why suggestions wouldn't work, or were done better with a different approach. Even though B programmers were competent and motivated and access to documentation, not having the understanding that A programmers had clearly worked to their disadvantage.
Case 2 concerns a large real-time system for monitoring industrial production activities. This case is similar: the programmers who developed the system had a better intuition of how to debug faults or adapt the operation of the system than outside programmers.
The conclusion Naur takes is that using or modifying a software system is dependent on a history of working closely to it. (Honestly, this seems a bit obvious to me in 2025; maybe in the 80s programmers were seen as more of an interchangeable assembly line worker.)
Can a non-programmer vibe coder have theory of a program? No, not at all. This means that vibe coders cannot modify the code that the LLM gave them. They can at best notice these bugs and instruct the LLM to fix them, but since the LLM produced the bug in the first place it's completely uncertain whether or not
Can an LLM have a theory of a program? Sort of. I'll bring up a couple personal anecdotes. First, I gave ChatGPT 4o and 5 a copy of my obfuscated Memory puzzle game written in Python with Pygame, and asked it to describe what the program was. The program is 170 lines long and all variable and function names have been changed to meaningless short names such as m()
or ww
. Both models were able to correctly identify it as a Memory puzzle game. (However, it's unknown if this was because it deduced this or the source code itself was already a part of its training data, given that the source had long been on the internet.)
But also not: nearly all of my experiments with generating code have involved bugs and mistakes. The fact that LLMs need repeat attempts, even for small programs, indicates that there is no theory that exists in the "mind" of the LLM.
Further, what's unknown is if its successes scale. A 170 line Python script is not that complicated. Would the models work at the level of hundreds of thousands or millions of lines long? Given that the context window of the largest LLMs is still a couple hundred thousand tokens, it's impossible for LLMs to comprehend large software systems used in production.
An additional experiment I'd like to do is see if LLMs can be used as antivirus or malware detector programs. If an LLM can generate a theory of the program from the source code, it should be able to determine if the source code carries out malicious activity. To extend this even further, I'd like to see if LLMs could develop a theory of the program from the compiled binary.
Ryle's Notion of Theory
Gilbert Ryle wrote a philosophy book in 1949, The Concept of Mind, which uses the term "theory" to mean an understanding of a concept such that a person who possess a theory can answer questions about the concept, learn from the examples of others, detect misconceptions about the concept, and offer suggested fixes. That seems straightforward enough.
Naur also explains that it isn't even possible for a programmer's theory to be expressed in terms of rules or criteria. I'm not quite sure I agree with this; I believe documentation can be written such a new programmer can be onboarded without needing mentorship from previous programmers. I think the reason documentation is often insufficient isn't because it's theoretically impossible; it's just that documentation isn't prioritized. Once the software works, organizations want to ship it and the docs are neglected as a "nice to have" feature.
TODO
The Theory To Be Built by the Programmer
Naur says that the Theory Building View of programming states that the programmer's theory has primacy over, specifically, user documentation and specifications. Sure, I agree with that. But he left out other forms of documentation related to the source code such as code comments and documentation specifically about the source code.
But anyway, Naur says there are three ways that the programmer's theory "transcends" user documentation.
First, the programmer having the theory can explain and answer questions about how the software relates to the real world problem it solves.
Second, the programmer can explain why each part of the program is there and how that part contributes to the solution to the real world problem.
Third, the programmer respond constructively to demands for modifications or extensions to the program.
Sure, no amount of quality documentation can anticipate every possible question about a piece of software and provide an answer the same way a human programmer with a theory of the software can. But that's obvious (at least to me as a software developer in 2025.)
TODO - reasoning models?
Problems and Costs of Program Modifications
I do like this bit: "Second, the expectation of the possibility of low cost program modiciations conceivably finds support in the fact that a program is a text held in a medium allowing for easy editing." I could see how non-programmers (especially managers) could think of programming as just typing and ask for "small changes" or "just one new feature" and think it's a small ask. After all, code is just text and programmers just type text all day, so why couldn't they just make this one change? The Theory Building View of programmings holds that programming is not just typing. (As an author, I am also well aware of the fact that writing is not just a task of linearly typing out words one after another from start to finish.)
I get the sense that this section is a response to grievances that existed in 1980s software companies. But this also exists today in essential every industry and human endevour. It's easy for outsiders to take a "I assume anything I don't understand must be easy" view or ignorantly suggest "Why don't you simply..." without realizing that their suggestion is easier said than done.
Naur also has the complaint that software is also asked to be "flexible" so that it can be adapted for features that aren't immediately needed, but may be needed in the future, without realizing that flexibility is itself a feature that is expensive to produce. I can see this from my own experience; part of what makes "throwaway code" so easy to write is that it only needs to work once, and I don't have to worry about changing it, adding new features, carefully documenting and publishing it, and offering support for it. Adding flexibility to the design of a piece of software requires a lot more careful consideration, which is in line with the Theory Building View of programming.
Futher, Naur states that source code can be degraded by modifications made by programmers who don't have the theory of the program. I can also attest to this from personal experience: I've received pull requests with "small changes" that don't alter or add that much in the way of lines of code to some of my open source projects. But if I accepted them (especially if I accepted all of them), they would make the source code worse: bloated with semi-useful, redundant, and/or not covered by unit test features that make developing the theory of the program harder for future contributors. The adage "Writing isn't finished when there's no more to add, but no more to take away" applies here.
Every programmer has had the experience of spending hours to debug a problem that turns out to be a one line change, or even a one character change. This reinforces that a program is not just text and programming is not just typing code. The programmer must have a theory of the program and understand how the parts interact with each other, since even small changes can have cascading effects on many other parts of the program.
TODO - Suggesting changes and additional features.
Program Life, Death, and Revival
Naur uses the metaphor that the programmer or programmers who create a program have given the program life. When the programming team behind the program dissolves, the program "dies". The software is all still there and can still be run, but the program is "dead" because no change (such as fixing bugs or adding features) can be made to it: "The actual state of death becomes visible when demands for modification of the program cannot be intelligently answered. Revival of a program is the rebuilding of its theory by a new programmer team."
This is great and useful perspective to apply. You can still have the software and source code itself. But without programmers who understand the "whats" and "whys" of the software design, it is effectively dead. From this, we take away that programs are only "living" as long as they can be updated, not as long as they exist.
Where I disagree with Naur is that he says a theory of the program can only be gained by mentorship of another programmer with the theory: "A very important consequence of the Theory Building View is that program revival, that is reestablishing the theory of a program merely from the documentation, is strictly impossible." Sure, this is the ideal way, but it is possible (though inefficient) to understand a program by reading its source code. Reverse engineering is difficult and messy, but it is possible.
Perhaps I'm not understanding something Naur is saying. Earlier he did say "user documentation" as in the user manual of how to use a piece of software. But since we are talking about programmers, I assume that "documentation" would also include the source code.
The next part I'd say is controversial: "In preference to program revival, the Theory Building View suggests, the existing program text should be discarded and the new-formed programmer team should be given the opportunity to solve the given problem afresh." This "why not rewrite it from scratch" is a tempting but often a mistake. (See also, the history of Netscape Navigator, "rewrite it in Rust" discourse, or the Elon Musk-led DOGE (failing) efforts to rewrite lots of existing American government software systems.)
I've even gone as far to say "Let's rewrite it from scratch" is an idiot's idea of a smart idea, along with measuring programmer productivity in lines of code written (that is, treating code as text and programming as typing.)
Perhaps this was a more viable strategy in the 80s when software was less complicated?
Method and Theory Building
In summary, this section argues against the idea that there could be some sort of written out recipe for producing software and rather the Theory Building View argues for "a collection of suggestions aiming at stimulating the mental activity of the [programmer]". Naur also writes that there is no "scientific method" in the sense that scientists follow some kind of N-step process for producing scientific results. I feel like this is captured by the adage, "Science is more art than science." So, too, with programming. Naur writes, "It follows that on the Theory Building View, for the primary activity of the programming there can be no right method."
Naur also writes that comparing and judging any given process that claims to efficiently produce programming is unlikely, given there are too many variables to take such a controlled-experiment approach.
I find nothing controversial about these statements.
Programmers' Status and the Theory Building View
Last, Naur argues that programmers should not be seen as interchangeable assemblyline workers but rather permanent owners responsbile for a program or parts of a program. Naur writes, "Another related view is that human beings perform best if they act like machines, by following rules, with a consequent stress on formal modes of expression" which reinforces this programming-is-not-assemblyline-work argument.
I find nothing controversial about this.
Conclusion of Peter Naur's "Programming as Theory Building"
Much of what Naur writes here seems obvious to me, an experienced software developer in 2025. Perhaps this is a case where new, innovative ideas of the past have become the normal background ideas of the present. Either way, I'm glad I read and did a write up of this essay even if it didn't necessarily tell me something I didn't know already. Much of my learning about the development of software came from my computer science undergrad education, Joel Spolsky's blog in the 2000s, random Slashdot and Reddit posts, and years working as a professional software engineer. I've written several, multi-hundred page books on programming, but the fact that these books only represent a fraction of my programming knowledge really drives home how much I've learned over twenty years of programming that exist as a "theory" in my head. Even now, the number of draft blog posts related to software development is over a hundred. I wish for continued good health and motivation to write down this knowledge so that it's accessible to others.