February 27, 2008
Imaginative, Aesthetic, Executable Writing
I just wrote up some notes toward a talk at the Codework workshop at WVU. I figured I’d drop them in here, for those interested in the aesthetics of programming and the relationship of programming and creative writing.
I start with a difference between computer programming and what is traditionally called creative writing: Code has both a human meaning and a formal machine semantics, while creative writing in the usual sense has only human meaning — it cannot be compiled and executed on a computer.
By “machine semantics,” I mean that the program has a meaning because of how it runs on a machine, a computer. This idea is a commonplace of research in programming languages. A specific formulation of this type of semantics, for instance, is the operational semantics, which can be used to prove properties of programming languages. I am not claiming that the computer is a device that makes meaning for itself or that programs are meaningful to computers, only that they have this different sort of meaning because they are instructions that cause machines to operate.
In using the term “human meaning,” I am stating that a person can read a computer program and make sense of it. To do this, the person must run the program in his or her mind to some extent, simulating what the computer would do and understanding it. This relates to the program’s machine semantics. But there are also features of the program that have no meaning in terms of how the program operates, but which do signify to people. Variable names, the names of functions, subroutines, methods, labels, and so on, and comments are some of these features. The choice of a particular way of writing code when there are several equivalent options (using “while” instead of “redo” in Perl, for instance, or a more or less “Pythonic” way of doing the same thing in Python) also allows programmers to determine style and signal meaning to people.
Programs are typically read by many people. They will certainly be read by the programmer as the program is initially written, expanded, refactored, and revisited. They will be read by managers and collaborators. They will be read by people working to port the program to a new platform, package it for distribution, or fix bugs. And of course they may be read by people learning about programming or just curious about the workings of the particular program. Given this readership, the human meaning of code is not insignificant on a practical level, and programming practices have acknowledged this.
Because these two aspects are present and are particular to code, the interplay between them is particularly interesting, and, in fact, I believe it is the locus of a new type of creative writing practice in which code itself is the thing written. That is, programming does not inform creative writing or vice versa; the same activity is, completely, both a programming practice and a creative writing practice.
Here are some programming practices and a description of how they engage these two levels of meaning:
Refactoring. The process of revising a program so that it is streamlined, clear, and meets coding guidelines or “best practices.” This mainly engages the level of machine semantics, at least in most of my refactoring, but it also deals to some extent with the level of human meaning because comments may be added and the program may be reorganized for the purpose of better understanding. However, the changes being made in refactoring are usually straightforward, aimed at better engineering and adherence to standards. There may be an art of programming, but it is hard to see refactoring as an imaginative or poetic process.
Compression. This is undertaken by those participating in Perl Golf, where the object is to write a program in as few “strokes,” or keystrokes, as possible. The problem to be solved is fixed and the goal is to accomplish a solution with extreme economy in program size. This mainly engages the level of human meaning — and then, only as a side effect. Compressed programs must all do the same task, so their machine semantics must be the same, but shorter ones will often (not always) be significantly harder to understand. Analogies can be drawn to constrained writing and competitive traditions of poem-writing, but, for different reasons than with refactoring, it is difficult to see this practice as highly expressive or poetic.
Obfuscated coding. Competitors are invited to write short programs that do anything they like while making the code for these programs intentionally hard to understand. Both levels are deeply engaged, with programmers having the option to pursue unusual machine function and to cloak the human meaning of their programs in clever ways. Although making programs intentionally hard to understand is not the only interesting way to code with regard to human meaning, it is an effort that resists the usual values of elegance, simplicity, and clarity. In many of the best obfuscated programs, the visual appearance of the code relates interestingly to its fuction — in some cases, the code itself is used as data by the running program — and obfuscation is achieved both my making the program’s workings byzantine and by choosing very difficult-to-understand means of implementing these workings. Obfuscated coding is one type of programming that is a writing practice and is also highly creative.
February 27th, 2008 at 11:30 pm
I personally find the most fascinating aspect of the two levels of meaning to be the various development tools that facilitate the process of writing and reading code and how they have radically transformed the aesthetic experience of programming over the years. For example, a few months ago I switched from Eclipse to IntelliJ IDEA for Java development, and the overall feeling of reading/navigating and writing the same body of code was completely different (and a little more pleasurable overall).
My first thought from the three categories of programming practices you listed (and I think they are good ones) was that there is plenty of industry effort put into optimization and automation of those practices, directed towards more efficient human-readability of code for practical software development purposes. In Java development we rely heavily upon features like Eclipse’s syntax highlighting and refactoring tools, Proguard’s automated code compression and obfuscation, etc. I’m wondering if some sort of connection between these practical tools designed to enhance code readability and programmer efficiency and the ‘handmade’ methods of creative code-writing practices could be developed more explicitly along these lines.
Perhaps the development of automated tools in these categories (eliminating the individual skill as a practical necessity) is precisely what opens up the space for their possibility as more explicitly ‘poetic’ coding practices? For example, does the common wisdom that ‘nobody in their right mind codes in assembly anymore’ implicitly encourage ‘coding in assembly’ to become acknowledged as an effort in creative writing?