Now we have this insight

This week we read up to frame 53, on page 16 of The Little Learner.1

The aesthetics of recursion

This week the authors treated us to an extremely concise introduction to the theory of recursion. They presented recursion as a strategy of extreme parsimony. Recursion allows us to write “interesting programs” with no loops. Recursion allows us to implement integer addition without using +. One member of the group marvelled at the resulting programs. He found them elegant. Did anyone else?

We discussed more largely the value of parsimony in reasoning. One member of the group observed that parsimony—or elegance—is an aesthetic value that transcends disciplinary boundaries. In a recent article for Critical Inquiry, Imogen Forbes-Macphail observes that

Like mathematicians, literary scholars find beauty in the pursuit of their work; in the products of that work (critical arguments or scholarship); and in the objects of that scholarship, literary artifacts themselves. (2025, p. 481)

Forbes-Macphail is not the first to identify a significant aesthetic dimension in scientific thought, though it is interesting to argue that the aesthetics of mathematical and literary inquiry are similar. What does elegance mean in literary criticism? Do literary critics have the same relish for parsimony as LISP hackers like the authors of The Little Learner? Is an interpretation of The Rover more powerful if it can be made using fewer concepts? The old debate among creative writing instructors, about the merits of ‘minimalist’ and ‘maximalist’ style, rears its head again.

This discussion hearkens back to Knuth’s theory of ‘psychological correctness’, which we discussed last year. I also note Douglas Hofstadter and Melanie Mitchell’s brilliant argument about the vitality of ‘aesthetic perception’ in science, in their jointly-authored chapters for Fluid Concepts and Creative Analogies.

Now we have this insight

Several times in the exposition, the authors claim that something “gives us an insight,” or that we now “have this insight.” “Do we?” quipped one member of the group.

The central conceit of the book is that we, the readers, are identical with the voice in the second column. The second voice models our own experience. Of course, this whole literary structure implies that we are not the voice in the second column. The book constantly entreats us to compare ourselves to this model student, and respond to the teacherly voice in the first column in our own way. The irony of the form finds its counterpart in the irony of the reader’s response.

Why do we ‘invoke’?

The idea of recursion is that a function “invokes itself.” We paused for a while on the idea of “invocation.” Why is it that we “call” or “invoke” functions? What is the underlying metaphor?

The discussion recalled to me these famous sentences from the beginning of The Structure and Interpretation of Computer Programs:

The evolution of a process is directed by a pattern of rules called a program. People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells. (1996, p. 2)

One member of the group preferred “invoke” to “call,” for the very reason that it implies that the “invoker” has command over the function they summon to their bidding. On the final verge of computation, at the very brink of the machine, when symbols have lost their meaning and the stack trace has buried itself in silicon, the programmer may find herself in the position of Byron’s Manfred:

I have no choice; there is no form on earth
Hideous or beautiful to me. Let him,
Who is most powerful of ye, take such aspect
As unto him may seem most fitting.—Come!

“Come, add1!” cries the wizard in his misery. “Come, add1, and increment my integer!”

The efficiency of Scheme

One member of the group asked how it is possible to write efficient programs in Scheme, when recursion is required for all looping.

The answer: tail-call optimisation. A topic slightly off the main track of our Critical Code Studies group! But a fascinating one regardless… parsimony strikes again.

References

Forbes-Macphail, Imogen. “The Four-Color Theorem and the Aesthetics of Computational Proof.” Critical Inquiry 51, no. 3 (March 2025): 470–91. doi:10.1086/734121.

Hofstadter, Douglas R., Daniel Defays, David Chalmers, Robert French, Melanie Mitchell, and Gary McGraw. Fluid Concepts and Creative Analogies: Computer Models of the Fundamental Mechanisms of Thought. New York: Basic Books, 1995.

Sussman, Gerald J, Julie Sussman, and Harold Abelson. Structure and Interpretation of Computer Programs. Second edition. Cambridge: MIT Press, 1996.

Notes

  1. Due to a cognitive deficiency of the group leader, we did not actually complete Chapter 0, which we would have had ample time to do… 

What is, was and shall be

In our session this week, we continued to learn the basics of the Scheme/Racket programming language, working though pages 4-8 of The Little Learner.

As so often happens in close reading, our attention was arrested by an apparently innocuous word: “is.” The word “is” has a peculiar meaning in the language of the book. The authors frequently write that something “is” or “is the same as” something else. For example, they pose the question

What is

(area-of-rectangle 3.0)

?

The answer:

(λ (height)
  (* 3.0 height))

Or again later:

The expression

(add3 4)

is the same as

((λ (x)
  (+ 3 x))
 4)

There is a curious inversion to their presentation. First they present a series of these examples, where s-expressions are evaluated, some involving closures, in which a higher-order function returns a new function that ‘remembers’ some values passed to the higher-order function. Then, they admit that their use of “is” and “is the same as” is not entirely idiomatic:

This way of remembering arguments passed in for formals of outer functions inside inner functions is known as β-substitution.

In other words, the word “is” actually means “can be transformed into via β-substitution.” Two s-expressions “are the same expression” when they can be transformed in this way. But what does this transformation entail? It entails taking the name of something, e.g. add3, height, area-of-rectangle, and replacing it with its value. Is “is” the right word for this? Is the name of a thing “the same as” the thing?

This use of “is” conflicted with intuitions we had in the group. It seems paradoxical to say that the name of something “is the same as” the thing itself. Of course, it is reasonable in the context of evaluating Scheme code. Whenever the code is run, it will be evaluated, so there is a sense in which the code simply is what it evaluates to. This sense of “is” also makes sense in an intellectual culture dominated by mathematics. In everyday algebra, there is no real distinction between equality and identity.

$$3 + 2$$

really is

$$1 + 4$$

Isn’t it? They are equal. Who cares how they are written?1 Seeing this “is”, of course, can take some work. How many people can really remember why $$a^2$$ really is $$b^2 + c^2$$ in a right triangle?

In everyday life, we are quite happy to “dereference” or “substitute” names for the things themselves. When I ask you to “pass the pepper,” I’m quite happy when you hand me the pepper grinder. You ask, “Is this what you wanted?” I reply, “Yes, it is!”

But nonetheless there is something alarming in being told that two things “are” one another when you haven’t internalised the substitution process that allows you to move between them. And names do have a reality of which we are sometimes reminded. If I ask a Canadian to “pass me the pepper,” and they give me a capsicum, I may be disappointed.

The whole discussion reminded me of piece by Lewis Carroll, in which a person’s name has a name, which itself has a name, which itself has a name, and so on. I was sure that this infinite regress featured in Gödel, Escher, Bach, but I have tried and failed to find either the Carroll Story or the Hofstadter variation on it! Is an intimation of a thing the same as the name of a thing? Or is the intimation the thing? Or is the name the intimation? Can a vague recollection be substituted for a textual authority? Or only for a vague apprehension…?

We recommence next week on frame 24, at the top of page 9.

  1. I’m sure there are varieties of algebra where identity matters—but that is way beyond my knowledge! 

Psst! Psst! Psst!

Today we commenced The Little Learner, the text that will occupy the group for many months to come. We read the Preface and the first page of Chapter 0.

Our discussion focussed mainly on the book’s authorial persona and implied reader. For those of us in the group who have a mainly adversarial attitude towards AI, the book presented a challenge. Isn’t deep learning interesting and fun? Aren’t the algorithms elegant and surprisingly simple? Shouldn’t everyone dive into this fresh and exciting area of research, and learn how to do it?

To invite the reader into the text, Friedman and Mendhakar carefully establish the reader as a novice, and themselves as kind, avuncular teachers. The reader need only know “high-school maths” and have a minimum of “programming experience.” The book proceeds from these foundations in a strict order, to build up from simple pieces the whole complex machinery of modern deep learning.

As some in the group observed, this “novice” reader was already expected to know some terms of art. Concepts such as “problem domain,” “equalities,” “invariants,” “superset” and “subset” were introduced as though they were the general coinage of the realm. Of course, all textbook writers face the problem that their students need to somehow learn the language that even makes it possible to express knowledge of their subject. How can you learn anything about a topic without having the words to describe the topic? But we as a group are intrigued to see precisely who or what these writers assume an interested and relatively ignorant reader to be as the book progresses.

We discussed the possible ideological implications of the book. Is this a book that subtly asserts a “tech-bro” persona? Or does its goofy and academic tone bespeak a different attitude? In our disciplines, we worry endlessly about surveillance capitalism, about the power of tech billionaires, about the algorithmic mediation of human interaction. The writers of The Little Learner sidestep such issues. Deep leaning is fun. It’s for categorising cat photos, not for empowering intelligence agencies to more rapidly scan citizens’ text messages. It’s something anyone can do as a hobby, rather than a tool used by rich and powerful people to make themselves richer and more powerful.

Everyone agreed the book is fun, and the topic is interesting. We will see in coming months how we can reconcile the fun with the cultural critique.

Any code written in the sessions can be found in the Github repository for this reading.

The End of Literate Programming

The end of the affair

At our final meeting for 2024, we completed reading Knuth’s Literate Programming. In the final section, Knuth considers “Retrospects and Prospects” for literate programming. In this section, Knuth is explicit about who literate programming is for: computer scientists and systems programmers, rather than hobbyists. This context justifies many of Knuth’s arguments throughout the essay, about the kinds of literacy assumed by the WEB system. But it also widens the main gap in his philosophy—the gap between the programmer and the reader. He anticipates the programs will become works of literature, which implies a wide readership, but he restricts WEB to a small subset of people, resulting in a restricted writership. In this way Knuth sharpens the literary aspect of his enterprise, for indeed literature too is written by the few for the many to consume.

With that, our first major reading for the group came to an end.

After the end

We spent some time looking at the upshot of Knuth’s new programming system. On his website, he has published many literate programs, in addition to publishing three books written in either WEB or CWEB, which contain the programs for TeX, Metafont and the MMIX virtual machine.

Literate programming has inspired many programming systems, but not in the manner Knuth proposed. He saw WEB as a system for highly skilled programmers to write complex software systems. But WEB (and its descendent CWEB) have not found much use in this domain. Instead, programming language designers have designed ever more capable documentation-generation systems, which allow software to be composed in a more conventional format, but with excellent computer-generated documentation. Python includes pydoc as part of its standard library, for example, while Rust ships with rustdoc. Such tools allow a developer to include documentation in their code, and generate attractive websites for their software. They do not support the creation of elegant books of the kind that Knuth prefers, and in particular, do not free the programmer from the sytax of their chosen programming language.

The Knuthian ideal of literate programming has caught on in a different community: data science. Statisticians, digital humanists, data analysts, lab scientists and others frequently use tools such as EMACS org-mode, RMarkdown and Juypter Notebooks to write their software. This form of literate programming is nonetheless distinct from Knuth’s. Knuth foresaw systems programmers building complex reusable systems using literate tools. Data scientists tend to write more ephemeral, simple programs, which analyse a particular dataset or form the basis for a particular article or report. When a data scientist does take the time to develop a more complex and reusable piece of software, they are more likely to do so in the form of a simple R, Python or Julia package. While it is possible to write such software in a more literate style using tools such as nbdev, this is not a common practice.

It is a pity that Knuth’s vision of programming-as-literature has not gone mainsteam. Source code is the primary medium of communication for millions of people who work every day as programmers. They write software that affects all of us, and if this software were readable by the general public, then the systems that govern our lives could in principle be more open and democratic. Even an experienced programmer can find it difficult to find a reading path through a complex program. If essential pieces of software such as MediaWiki (i.e. Wikipedia), TensorFlow or Bluesky were written and published in a Knuthian style with a linear narrative, then more people might be inclined to read and debate the code.

What next?

We will reconvene in February 2025, as the summer recess draws to a close here in Australia. Stay tuned for our next reading, which will involve the source code of a Large Language Model. Tell then, Happy Holidays!

Faulkner's Typewriter

In this session, we read sections L and M of “Literate Programming,” which consider the economics of WEB and its relationship to prior work.

Economics of a text editor

Where his earlier writing was produced by hand, the result of a careful and meticulous craftsmanship, in the 1950s Faulkner developed a messier, faster method that relied solely on a typewriter. (DiLeonardi 2024, p. 177)

How does a writing tool affect the writer? Knuth argues that WEB code is faster to write, because WEB imposes a salutary discipline on the programmer at the time of composition. It may take a little longer to write Version 0, but the code will be so much better that it will only be a short step to Version 1.

One member of the group drew a comparison with William Faulkner, whose practice changed significantly when he adopted the typewriter in the late 1950s. As DiLeonardi (2024) explains, Faulkner’s typescripts and manuscripts are quite different documents. His handwritten manuscripts are meticulously crafted. Faulkner claimed that he hadn’t changed a word of As I Lay Dying (1930) in the writing, but the flawlessness of the manuscript suggests a close process of real-time editing. His typescripts are different. He complained that it was “too easy” to put words on the page. They are full of typos, and the novels he wrote on a typewriter, such as The Town (1957) are looser and less crystalline that his handwritten books.

Knuth’s adoption of WEB had, in his own estimation, the opposite effect to Faulkner’s adoption of the typewriter. He claims that code he once wrote carelessly he now writes carefully. When he writes a WEB program, he is in “expository mode.” He imagines that he is explaining the code to someone else, and this mode of thought makes for better programming.

Knuth is trying to advocate WEB as a practical programming tool, and couches his arguments in terms an IBM executive might understand: will this tool reduce labour costs? But in our group we observed a different side to the argument. In his discussion of the “expository mode,” Knuth once again undermines his idea about WEB programming as a “stream of consciousness.” The expositor does not simply let their consciousness stream. They shape that stream for the benefit of a student or a reader. Although he doesn’t clearly theorise their role, Knuth is aware of the importance of the reader, and of the rhetorical situation of the programmer.

He does want readers. The section ends with a delightful expression of Knuth’s burning desire to promulgate both his code and his coding tool.

The rhetorical function of acknowledgements

Section M is essentially and “acknowledgements” section, or an “awards acceptance speech,” as two wits of the group put it. What it is doing in the article?

Partly the acknowledgement of prior work justifies his own undertaking. He makes the radical claim that “it is worthwhile to consider every program as a work of literature,” and wants to establish precedents.

Every program? We discussed this with some astonishment. In our own fields—literature and art history—there is habitually some distinction between what is literary or artistic and what is not. A bureaucratic form is certainly writing, but doubtfully literature. Painting a door is certainly painting, but probably not art. Should every program be see as a piece of literature?

There are two problems with Knuth’s claim, one obvious, the other more subtle.

The obvious problem is that many programs are boring, technical or uninteresting. There are programs that resemble shopping lists and bureaucratic forms, as well as programs that resemble haikus or essays. Perhaps Knuth really is advocating a Dadaist aesthetic, and wants to claim that even the humblest little utility program can be dignified as literature, if only it is written and documented properly in WEB.

The more subtle problem is, again, readership. Another class of things we usually exclude from “art” or “literature” are creative works that are intended for coterie audiences. Patents, blueprints, scientific articles—these things are usually excluded from the art-world or the literary sphere. Art is for the “public.” Literature is for the “general reader.” Can literate programs be so? Perhaps Knuth is advocating an esoteric literature. It may appeal to a small audience, but it has the same aesthetic values and careful creative purpose as literature intended for the public.

It seems more likely that every is hyperbole, or simply not a claim that Knuth carefully considered before he made it. But it is tempting to view Knuth as a kind of William Blake of programming, simultaneously furious in his esotericism, unorthodox in his standards of beauty, and utterly committed to his crazy craft as a form of expression that reaches out widely into society and lengthily into the future.

Next week, we conclude our reading of “Literate Programming.” And move on to something new …

References

DiLeonardi, Sean. “Mediation, Stream of Consciousness, and the Faulknerian Voice: As I Lay Dying to The Town.” Twentieth-Century Literature 70, no. 2 (June 1, 2024): 173–98. doi:10.1215/0041462X-11205357.