wiki.paulswartz.net

Navigation

Recent site activity

Home‎ > ‎DivisionIII‎ > ‎

Poetics of Programming

Literature, according to J.L. Austin, is a parasitic use of language: to be taken seriously, one must "not be joking, for example, nor writing a poem."[1] He makes this statement in the context of performative utterances, phrases that cause something to happen (e.g. "I do"). Still, this is a strong phrase, given that literature is a wildly popular user of language. But he does have a point: literature does work with language in a different way from other uses. It is different from a normal conversation because a conversation is not a text. In a normal conversation, the words we say are taken as truthful by the other party, and they have an influence on our world. These features are not true of literary works.

Literature is different from other uses of language. It is different from conversation or older oral stories because it is naturally a text. Literature is composed visually; it is written, be it on paper or on a computer screen. Conversation is founded on the metaphor that meaning is present in the words, and that speech, by requiring presence, is better at conveying meaning.[2]

However, this is not functionally true. Writing can have meanings that are not expressible in speech. Derrida calls this différance, something that is possible to express in writing but not in speech. In his essay of the same name, he writes that "this graphic difference (a instead of e)...between two vowels, remains purely graphic: it is read, or it is written, but it cannot be heard."[3] The word différance is only distinguished from difference by a change in writing; the pronunciation does not change. In this way it is self-referential: it represents a concept that includes itself. Différance is derived from the Latin verb differre which has become two different words in English: to differ (be different from) and to defer (to delay in time).

The linguistic sign is based in difference: it is defined against all the other signs which it is not. However, the sign also has meaning by standing in for something that is not present, is a kind of "deferred presence."[4] Différance incorporates both of these meanings into a single word, representing both natures of the linguistic sign simultaneously.

Literature is also different from non-fiction work. The goal of a non-fiction piece is to convey information about our world. Ideally, it conveys that information in a way that allows its audience to grasp all of it. Literature can also convey information, but more often it focuses on telling a story. At the very least, literature creates a world, and controls the characters and makes changes to that world.

Plays are also different from other kinds of literature. They are written down as a script, but are performed by actors and actresses. They create a world, generally not through the language but through the scenery on stage. The language is used to develop the characters who populate that world, and the focus is on those characters. The world rarely changes, in part because of the difficulty of changing scenery mid-act. Also, because the interaction between the audience and the actors and actresses is only through dialog, the playwright cannot incorporate the narrative descriptions that allow for world-changing in textual works.

Poetics is the study of literary discourse, of what makes a work literary. There are many views about what makes a work literary. For simplicity and space, I will focus here only on two. These two views on what makes a work literary also have two different ideas on who puts in the effort to make literature. To simplify Roland Barthes, I will call these views writerly and readerly.

For Barthes, the writerly text is the one that the reader produces instead of consuming: "the goal of literary work (of literature as work) is to make the reader no longer a consumer, but a producer of the text."[5] No criticism of a writerly text is possible, because "any criticism...once produced, would mix with [the writerly text]."[6] A reader of a writerly text is also creating the meaning of that text.

The readerly text is "[the writerly's] countervalue, its negative, reactive value: what can be read, but not written..."[7] The readerly view is that the writer makes a work literary. The writer creates the images, the connections, the world, in the work, and the way the writer writes the work makes it literature. Literature is distinguished from non-literature by the presence of features in the text: literature is figurative, non-literature is literal; literature uses tropes like irony, sarcasm, metonymy, apostrophe, non-literature uses plain, natural language. In short, this view holds that literature is a quality that a work possess; the literary is put into the work by the author.

The writerly view contradicts the readerly. The writerly is the idea that literature is brought to the work by the reader. The reader comes upon a text, and the way that the text is read creates a literature. Any work can be read as a literature. Reading a text as literature means bringing the meaning to the work. A work is literary because the reader brings a literary mindset to the work. The cut-up work of William Burroughs is a good example of this view. Because of the random nature of the ordering of the words in the text, the writer cannot bring anything to the text except the words. We as readers bring a mindset to the work, and look for the connections that appear in the text.

In Tzvetan Todorov's Introduction to Poetics, he outlines some of the general structures that he finds in discourses in general, and in literature specifically. There are two basic structures that are found in narrative discourse. One is the causal-temporal relationship structure. The order of the events, and the cause-effect relationships that link them, form a structure that carries the narrative along from event to event. Without this structure, there would be no narrative, only an unordered list of events.

The other is the thematic structure. Thematic relationships are much stronger for the reader than temporal relationships: "The logical [thematic] series is in the reader's eyes a much stronger relation than the temporal series; if the two go together, he sees only the first."[8] Themes play on our human desire to find meaning in stories. They provide an overarching structure of meaning beyond that of mere temporality. Temporal relationships are easy to find, but do not add much to our understanding. Use of literary tropes is an example of a thematic structure; repetition of important themes throughout a work is another.

Aesthetics is a closely related field of literary theory that tries to theorize what makes a work of art beautiful, what gives a work of art value. This value is supposed to be universally valid, so that everyone agrees on what is beautiful. However, the qualities that make art beautiful are elusive, especially in literature. In general, literary works of art are thought “good” when they produce an effect on the reader. This effect does not have to be good: works that elicit horror or sadness can and often are considered good literature. It is these two genres of literary theory, poetics and aesthetics, that I will attempt to direct at computer programming.

Donald Knuth was one of the first to try to bring the computer and the literary closer together. He thought that making programs more literary would alleviate some problems programs have, "issues of reliability, portability, learnability, maintainablity, and efficiency--are ameliorated when programs and their dialogs with users become more literate."[9] Knuth's idea was to combine the documentation with the code more closely, so that they become the same work. He called these works literate programs. The language he wrote these programs in is called WEB, because of how it tangles the documentation and the code, and how it can be untangled into a file that can be run by the computer or into a printable documentation file. Although he says "literate," the way he describes literate programs and compares them to novels, his use of the term seems much closer to the word 'literary.'

Literate programs are broken up into modules, which work similarly to functions in other languages. Modules can execute the code inside of other modules. Each module has a name and a description of what it does, along with the code that performs those actions. Modules represent one concept or action, and are listed as the programmer needs them. They do not have to appear in the order of their execution: unweaving the file takes care of ordering the statements appropriately.

How is this kind of organization literary? What similarities does it have with works of literature? For one, literate programs are mostly written in natural language. One goal of literate programming is to increase the amount and the detail of the documentation. By breaking the program into smaller parts, there is more total documentation and each section is small so understanding it is easier.

Literate programs also tell a kind of story. The opening sections set up the characters, the variables that will be used throughout the sections. The later sections are doing things with those characters, moving the story along. The second module of the CWEB (WEB for the C programming language) word count example lays out this structure explicitly:

2. Most CWEB programs share a common structure. It’s probably a good idea to have one module that states this structure explicitly, even though the elements could all be introduced in sections contributing to of the unnamed module if they don’t need to appear in any special order.

{ Global variables 4 }
{ Functions 20 }
{ The main program 5 }[10]

The fourth module sets up the global variables, and the fifth is the main program, the action of counting words in a file. Only later in the file (the 20th module) are the functions listed. However, they are referenced earlier that the main program, because in the C language, functions have to appear before they are called. By referencing the module of functions before the main program, the main program can use those functions.

This structure of characters followed by action is almost identical to the structure of narratives. Todorov sees narratives as a series of propositions in a sequence. His example of a proposition is part of a Russian fairy tale:

X is a young girl
Y is a king
Y is X's father
Z is a dragon
Z abducts X[11]

Each line in the proposition is a motif: "Motifs which change the situation are dynamic motifs; those which do not are static."[12] This proposition bears a striking resemblance to the PROLOG logic programming language. In PROLOG, this proposition would be:

young_girl(X)
king(Y)
father(Y, X)
dragon(Z)
abducts(Z, X) :- dragon(Z), young_girl(X), king(Y), father(Y, X)

The first four lines are static motifs, or facts in PROLOG; they make statements about the state of the world. In this case, they are setting up the characters for the narrative. The last is the dynamic motif, and it uses the function of 'abduction'; in PROLOG this would be considered a rule, because it states something that is true about the world. It makes the story move.

Here the narrative and the code have the same structure, a structure given to the work by the writer/programmer. This is the readerly view. The programmer puts the meaning into the code as she is writing it through the literate programming system. The abduction in PROLOG can only be true if the characters involved fill the appropriate positions. The meaning comes from that literary structure.

In the fairy tale, the actual characters are not relevant to the narrative. What matters is the positions they fill in relation to the other characters and the actions that must be performed. They are the "associated motifs"[13] of the narrative; the motifs that would fill out the characters or make the narrative more lively are "free motifs" because the author can freely leave them out of the story. In literature, free motifs are important because readers need more than just the action. They need a reason to care about the characters and what happens to them. The free motifs describe the characters, fleshing out the story and giving the readers a reason to care.

The writerly view is also relevant here. The computer does not execute a literate program differently from a non-literate one. In fact, every literate program contains a non-literate program which has the same effect when executed. Tangling a WEB program, for example, outputs a non-literate program that is executed. Literate programs do not run more efficiently, nor are they better at solving problems.

The differences are only for the humans reading the code. A programmer reads a literate program differently from a non-literate program. Literate programs encourage readers to follow their logic as one would follow a plot arc, and encourage programs to be written with reading in mind. Knuth went so far as to publish the woven versions TeX: The Program and Metafont: The Program verbatim, hoping that programmers would sit down and read them as they would a work of literature: for pleasure. He felt that programs should be addressed to humans, because people are the ones who are spending the most time actually reading the code:

Literature of the program genre is performable by machines, but that is not its main purpose. The computer programs that are truly beautiful, useful, and profitable must be readable by people. So we ought to address them to people, not to machines.[14]

Programs for Knuth are best thought of not as instructions to a computer, but as a description to a human of what a computer should do. I think that Knuth is correct here, even if literate programming is an excessive way to get the programmer to focus on the documentation of a program. "Programs are read more than they are written,"[15] and they are read, debugged, and updated by humans. Focusing on humans is how the best programs are written. They focus on the aspects of the program that interface with humans, be they users or other programmers. For example, the Python programming language uses indentation to represent structure. This is only visible to the human interacting with the source code: when the interpreter translates the program for the CPU, the indentation is not part of the translated code.

Literature never had to learn this lesson, as it was always targeted at human beings. The best literature too is targeted at human beings who are intelligent readers, who are willing to put effort into understanding a work, and a focus which I feel programmers could stand to emulate.

The question of who programs are addressed to is a difficult one. Computers are inanimate objects, like toasters or cars. When we write a program for the computer, we are engaging in the literary trope of apostrophe. Apostrophe is an address to an inanimate or absent object, something that cannot receive the address. When Shelly asks the West Wind, "O Wind, / If Winter comes, can Spring be far behind?"[16] he is using apostrophe. We do not normally address inanimate objects; we expect a response to our address. This makes apostrophe a strange use of language. Because it expects a response from the addressee, an apostrophe serves to anthropomorphize the object, making it like a human subject of a normal address. Only subjects have the power to respond to an address, to modify their behavior in reaction.

However, programming is not a normal address, and computers are not normal objects. Computers are not inanimate objects in the same way as others; computers return the values of their calculations to the programs. We can interact with them, changing how they function on the fly. Even the act of programming itself is a change in the computer's functionality. If natural language were used to address a computer, either by typing or speaking commands, there would be little difference between interacting with a human and a computer at the level of address. This would complicate the very possibility of apostrophe by complicating the definition of an inanimate object. The lack of response has been the rationale for apostrophe's application to inanimate objects, but if computers can respond in the same way as humans, then they do not need to be anthropomorphized: they are already humanlike. Programs would not longer be apostrophes, because the computer (presumably) could respond to the programs it (he or she?) was receiving. The concept of an apostrophe would have to be retooled to apply just to objects incapable of response, not just inanimate objects.

Instead of the program's apostrophe humanizing the computer subject, however, something different happens. The program itself – originally the address – becomes the subject, becomes humanized. In programmers' language, code is what does the acting and is thereby anthropomorphized.

This anthropomorphizing also comes from the program being a complex system. Programmers have immense respect for complex systems. Working with them all day, programmers know that programs can often take on a life of their own, and their results are often not fully understood even by the programmers who wrote the code. Programs, like other complex systems, are subject to unforeseen interactions causing unexpected results.

The human brain is also this kind of complex system, one which we recognize as human by default. Since programs and the human brain are both complex systems, past the comprehension of any single human, programmers address the program as a being of equal complexity to a fellow human. The entire field of artificial intelligence is based on this assumption, that programs are as complex and can demonstrate the same behaviors as humans.

All of this is relevant only if computers are in fact the target addressee of the program. Knuth says the opposite, and he is right to a point. Programs are directed at the humans who read them. Inline documentation (document that is in the same file as source code) is there specifically for the programmers who are trying to understand the code. But computers also have to be an addressee. Programs have to be written in a language that a computer can understand, otherwise the program is not useful. Programs have to straddle this line; they have to be effective descriptions to both humans and computers.

Moving away from poetics and back to aesthetics, experienced programmers have a well-honed sense of what makes those descriptions aesthetically pleasing. Some of the aesthetic values programmers find in code are: correct functioning, simplicity, conciseness, adaptability, and efficiency. The computer, nevertheless, does not care about these aesthetic values. It runs code the same way regardless of the aesthetics of the code. It does work less hard running code that is efficient, but that is not a value judgment from the computer. A human following instructions takes longer to follow complicated instructions, regardless of their value; more instructions simply mean more time spent executing them.

Correct functioning is the highest of these aesthetic values: "If a program doesn't work, measures of efficiency, or adaptability, or of cost of production have no meaning..."[17] All programs go through a state of non-functioning, like all works of literature go through a first draft. Programs which fail to perform their task are worse than bad: they are deceitful, since they purport to do an action which they do not; they complicate other programs which depend on them, now require working programs to be modified to work around the broken program; they require developers to stop working on newer software and go back to fixing code which should have been correct before. However, non-functioning programs can serve a purpose: they can be a kind of trial-and-error, a writer's journal for programmers, a way to experiment with how the computer executes the code. But these non-functioning programs are only useful if they serve to help the programmer write correct code in other places.

Literary texts have this as a goal as well, although it is perhaps not made explicit by writers. When an author creates a work, he generally has in mind a story to tell and an effect that he wants the work to have on a reader. The work, then, is considered a failure if that story is not told or the effect is not achieved. In a program, the story and effect are equivalent to the structure and the output off the code. Although this is more difficult in literature given the wide range of possible readers, knowing one's audience, as knowing what computer the code will be executed on, goes a long way toward mitigating the difficulty of achieving those goals.

Conciseness and simplicity are also very strong aesthetic values for most programmers, but not stronger than correct functioning. One style rule of programming is that a single function (block of code that performs a task) should not be any longer than a screen. This is conciseness.

This rule means that a programmer does not need to scroll the code around on the screen to see the whole function, and avoids forcing the programmer to keep parts of the function in her head. It also helps explain a big advantage of higher-level computer languages: with each line doing more work, a single-screen function does more work in the same number of lines.

Simplicity is a related concept, but refers more to structure than to length. Code that is simple has easy-to-understand relationships between the objects and functions that make up the program. It also means keeping either the depth or the width of the structure small. This is valuable because, for programmers to be effective, they need to be able to keep the program's structure in their heads, to understand how the parts fit together to make the program function. A program with a simple, thin structure can be kept in a programmer's mind much more easily than a complicated, deep one. Deep structures can also have problems with abstractions leaking from one level to another. Each level should be functionally distinct from the levels above and below, so that programmers do not have to worry about what exactly the other levels are doing. However, the deeper the structures are, the more likely it becomes that a programmer mixes levels; this not only makes the structure more complicated, but also makes the code less adaptable.

Adaptability is the ability of code to be taken and applied in a program different from the one it was originally written for, or to be used for a task other than that for which it was designed. Whenever they can, programmers recycle already written code, either by calling it in a function (ideal) or copying the code directly (poor). Calling the code in a function is ideal because it keeps the code in one place, so there is only one place to fix bugs or add functionality. If the code is copied, fixes have to be manually added to each place the code is copied. By reusing code, programmers avoid having to fix bugs in new code, or save time by having to type less.

Often, new programs are not designed with this in mind: they are just written until they work. However, as they get bigger, they become harder to manage without some rewriting. They are refactored: broken up into functions and/or moved into a library where multiple programs can share the same code. Code that allows for use by multiple programs is more useful, and hence more valuable. Adaptable code does not have to be written again, saving the computer's memory and the programmer's time.

Efficiency, as mentioned earlier, is one of the few aesthetic values which affects the computer directly. It takes less time, both wall time (time on a clock) and CPU time (instructions run), to execute efficient code. Programmers do strive to make their code efficient, but rarely at the cost of the other values. Computer hardware is cheap, relative to the cost of the software, and so generally writing less efficient software is more efficient in terms of programmer time. In fact, efficiency can be seen as an overriding category, and computer science tends to see code aesthetics "largely in terms of issues like computability and, especially, efficiency — efficiency of execution (speed), efficiency of production (writing), efficiency of maintenance (continual rewriting), or other efficiencies."[18] However, even though efficiency can stand in for values of conciseness and adaptability, correctly functioning code is still the primary value.

I think that this strong focus on efficiency is largely a factor of the business and the science being focused on the computer and not on the people. It is easy to measure how efficiently a computer executes a piece of code, but not as easy to measure how well a human comprehends what that code will do. But to write effective programs, the humans need to understand what the computer is doing with their code. Better programs focus first not on efficiency, but on correctness of effect.

This is the biggest lesson that computer science can take away from literature. Literature has always focused on effect first because without the effect the work can hardly be considered literary. If the work does not cause the reader to feel some emotion, then what kind of literature is it? Computer programs always have an effect; the goal with code is not merely to have an effect, but to have a specific effect.

The structure is also important for both literature and programs. The structure is how we as readers organize the narrative in our heads. Simple structures help us keep the program's meaning clear in our heads.

So why write all this about the aesthetics and poetics of programs? Perhaps it is best to start again with literature. We study and theorize about those fields because they help us understand why literature has such power over us and to direct that power. Technologies like writing are "utterly invaluable and indeed essential for the realization of fuller, interior, human potentials."[19] We cannot conceive of a modern world without writing and literature. Understanding how we can use those technologies allows us to make more powerful, more beautiful, better works of literature. Here, I have only outlined some of the aesthetic values that programmers currently use to judge programs. I hope that by following these aesthetic theories and applying their ideas to the computer, we can make more powerful, more beautiful, better computer programs as well.

Notes

  1. Austin, J. L. How to Do Things with Words. Cambridge: Harvard University Press, 2005. p. 6.
  2. For more on this metaphor, see "How do Programs Mean?" in this collection.
  3. Derrida, Jacques. "Différance." Margins of Philosophy, trans. Alan Bass. Chicago: Chicago University Press, 1982. p. 3
  4. Ibid. p. 9.
  5. Barthes, Roland. S/Z: An Essay. trans. Richard Miller. New York: Hill & Wang, 1975. p. 4.
  6. Ibid. p. 5.
  7. Ibid. p. 4.
  8. Todorov, Tzvetan. The Poetics of Prose. Ithaca: Cornell Univ Press, 1977. p. 42.
  9. Knuth, Donald E. Literate Programming (Center for the Study of Language and Information - Lecture Notes), 1992. p. ix.
  10. Levy, Silvio, and Donald E. Knuth. "wc: an Example of CWEB by Silvio Levy and Donald E. Knuth." CTAN. 12 June 2004. 15 Apr. 2007 <ftp://tug.ctan.org/pub/tex-archive/web/c_cpp/cweb/examples/wc.w>.
  11. Todorov. p. 49.
  12. Quoted in Todorov. p. 49. italics not mine.
  13. Ibid. p. 51.
  14. Literate Programming. p. ix.
  15. Eckel, Bruce. "Why I Love Python." 9th International Python Conference. Long Beach, CA. Mar. 2001. 15 Apr. 2007 <http://www.mindviewinc.com/downloads/pub/eckel/LovePython.zip>.
  16. Shelley, Percy Bysshe. "Ode to the West Wind." Norton Anthology: World Masterpieces, Volume Two. Ed. Maynard Mack. New York: Norton, 1995. p. 814-815. l. 69-70.
  17. Weinberg, Gerald M. Psychology of Computer Programming. New York: Van Nostrand Reinhold, 1971. p.19.
  18. Wardrip-Fruin, Noah. Expressive Processing: On Process-Intensive Literature and Digital Media. Diss. Brown University, 2006. <http://www.noahwf.com/dissertation>. p. 32.
  19. Ong, Walter. Orality and Literacy. New York: Routledge, 2002. p. 81.