10 PRINTprogram is typed into the Commodore 64 and is run. Output scrolls across the screen until it is stopped.
Computer programs process and display critical data, facilitate communication, monitor and report on sensor networks, and shoot down incoming missiles. But computer code is not merely functional. Code is a peculiar kind of text, written, maintained, and modified by programmers to make a machine operate. It is a text nonetheless, with many of the properties of more familiar documents. Code is not purely abstract and mathematical; it has significant social, political, and aesthetic dimensions. The way in which code connects to culture, affecting it and being influenced by it, can be traced by examining the specifics of programs by reading the code itself attentively.
Like a diary from the forgotten past, computer code is embedded with stories of a program’s making, its purpose, its assumptions, and more. Every symbol within a program can help to illuminate these stories and open historical and critical lines of inquiry. Traditional wisdom might lead one to believe that learning to read code is a tedious, mathematical chore. Yet in the emerging methodologies of critical code studies, software studies, and platform studies, computer code is approached as a cultural text reflecting the history and social context of its creation. “Code . . . has been inscribed, programmed, written. It is conditioned and concretely historical,” new media theorist Rita Raley notes (2006). The source code of contemporary software is a point of entry in these fields into much larger discussions about technology and culture. It is quite possible, however, that the code with the most potential to incite critical interest from programmers, students, and scholars is that from earlier eras.
This book returns to a moment, the early 1980s, by focusing on a single line of code, a BASIC program that reads simply:
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
One line of code, set to repeat endlessly, which will run until interrupted (Figure 95-1).
Programs that function exactly like this one were printed in a variety of sources in the early days of home computing, initially in the 1982 Commodore 64 User’s Guide, and later online, on the Web. (The published versions of the program are documented at the end of this book, in “Variants of 10 PRINT.”) This well-known one-liner from the 1980s was recalled by one of the book’s authors decades later, as discussed in “A Personal Memory of 10 PRINT” in the BASIC chapter. This program is not presented here as valuable because of its extreme popularity or influence. Rather, it serves as an example of an important but neglected type of programming practice and a gateway into a deeper understanding of how computing works in society and what the writing, reading, and execution of computer code mean.
This book is unusual in its focus on a single line of code, an
extremely concise BASIC program that is simply called
10 PRINT throughout. Studies of individual, unique works abound in the
humanities. Roland Barthes’s S/Z,
Samuel Beckett’s Proust,
Rudolf Arnheim’s Genesis of a Painting: Picasso’sGuernica,
Stuart Hall et al.’s Doing Cultural Studies: The Story of the Sony Walkman,
and Michel Foucault’s Ceci n’est pas une pipe
all exemplify the sort of close readings that deepen our
understanding of cultural production, cultural phenomena, and the
Western cultural tradition. While such literary texts, paintings,
and consumer electronics may seem significantly more complex than a
one-line BASIC program, undertaking a close study of
10 PRINT as a cultural artifact can be as fruitful as close readings of
other telling cultural artifacts have been.
In many ways, this extremely intense consideration of a single line
of code stands opposed to current trends in the digital humanities,
which have been dominated by what has been variously called distant
reading (Moretti 2007), cultural analytics (Manovich 2009), or
culturomics (Michel et al. 2010). These endeavors consider massive
amounts of text, images, or data—say, millions
of books published in English since 1800 or a million Manga
pages—and identify patterns and trends that
would otherwise remain hidden. This book takes the opposite
approach, operating as if under a centrifugal force, spiraling
outward from a single line of text to explore seemingly disparate
aspects of culture. Hence its approach is more along the lines of
Brian Rotman’s Signifying Nothing
(1987), which documents the cultural importance of the symbol 0.
Similarly, it turns out that in the few characters of
there is a great deal to discover regarding its texts, contexts,
and cultural importance.
By analyzing this short program from multiple viewpoints, the
book explains how to read code deeply and shows what benefits can come
from such readings. And yet, this work seeks to avoid fetishizing
code, an error that Wendy Chun warns about (2011,
51–54), by deeply considering context and the
larger systems at play. Instead of discussing software merely as an
abstract formulation, this book takes a variorum approach, focusing
on a specific program that exists in different printed variants and
executes on a particular platform. Focusing on a particular
single-line program foregrounds aspects of computer programs that
humanistic inquiry has overlooked. Specifically, this one-line
program highlights that computer programs typically exist in
different versions that serve as seeds for learning, modification,
and extension. Consideration of
offers new ways of thinking about how professional programmers,
hobbyists, and humanists write and read code.
The book also considers how the program engages with the cultural imagination of the maze, provides a history of regular repetition and randomness in computing, tells the story of the BASIC programming language, and reflects on the specific design of the Commodore 64. The eponymous program is treated as a distinct cultural artifact, but it also serves as a grain of sand from which entire worlds become visible; as a Rosetta Stone that yields important access to the phenomenon of creative computing and the way computer programs exist in culture.
The subject of this book—a one-line program for
a thirty-year-old microcomputer—may strike some
as unusual and esoteric at best, indulgent and perverse at worst.
But this treatment of
was undertaken to offer lessons for the study of digital media more
broadly. If they prove persuasive, these arguments will have
implications for the interpretation of software of all
First, to understand code in a critical, humanistic way, the
practice of scholarship should include programming: modifications,
variations, elaborations, and ports of the original program, for
instance. The programs written for this book sketch the range of
possibilities for maze generators within Commodore 64 BASIC and
across platforms. By writing them, the
program is illuminated, but so, too, are some of the main
platforms of home computing, as well as the many distinctions between
Commodore 64 BASIC and contemporary
Second, there is a fundamental relationship between the formal workings of code and the cultural implications and reception of that code. The program considered in this book is an aesthetic object that invites its authors to learn about computation and to play with possibilities: the importance of considering specific code in many situations. For instance, in order to fully understand the way that redlining (financial discrimination against residents of certain areas) functions, it might be necessary to consider the specific code of a bank’s system to approve mortgages, not simply the appearance of neighborhoods or the mortgage readiness of particular populations.
This book explores the essentials of how a computer interprets code and how particular platforms relate to the code written on them. It is not a general introduction to programming, but instead focuses on the connection of code to material, historical, and cultural factors in light of the particular way this code causes its computer to operate.
Third, code is ultimately understandable. Programs cause a computer to operate in a particular way, and there is some reason for this operation that is grounded in the design and material reality of the computer, the programming language, and the particular program. This reason can be found. The way code works is not a divine mystery or an imponderable. Code is not like losing your keys and never knowing if they’re under the couch or have been swept out to sea through a storm sewer. The working of code is knowable. It definitely can be understood with adequate time and effort. Any line of code from any program can be as thoroughly explicated as the eponymous line of this book.
Finally, code is a cultural resource, not trivial and only instrumental, but bound up in social change, aesthetic projects, and the relationship of people to computers. Instead of being dismissed as cryptic and irrelevant to human concerns such as art and user experience, code should be valued as text with machine and human meanings, something produced and operating within culture.
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
The pattern produced by this program is represented on the endpapers of this book. When the program runs, the characters appear one at a time, left to right and then top to bottom, and the image scrolls up by two lines each time the screen is filled. It takes about fifteen seconds for the maze to fill the screen when the program is first run; it takes a bit more than a second for each two-line jump to happen as the maze scrolls upward.
Before going through different perspectives on this program, it is useful to consider not only the output but also the specifics of the code—what exactly it is, a single token at a time. This will be a way to begin to look at how much lies behind this one short line.
The only line number is this program is 10, which is the most
conventional starting line number in BASIC. Most of the programs in
the Commodore 64 User’s Guide start with line 10, a choice that was typical in other books and
magazines, not only ones for this system. Numbering lines in
increments of 10, rather than simply as 1, 2, 3, . . . , allows for
additional lines to be inserted more easily if the need arises
during program development: the lines after the insertion point
will not have to be renumbered, and references to them (in
GOSUB commands) will not have to be changed.
The standard version of BASIC for the Commodore 64, BASIC version 2
by Microsoft, invited this sort of line numbering practice. Some
extensions to this BASIC later provided a
RENUM command that would automatically redo the line numbering as 10, 20,
30, and so on.
This convenience had a downside: if the line numbers were spaced
out in a meaningful way so that part of the work was done beginning
at 100, another segment beginning at 200, and so on, that
thoughtful segmentation would be obliterated. In any case,
RENUMBER was not provided with the version of BASIC that shipped on the Commodore
One variant of this program, which was published in the
Commodore-specific magazine RUN,
uses 8 as its line number. This makes this variant of the program
more concise in its textual representation, although it does not
change its function and saves only one byte of
memory—for each line of BASIC stored in RAM, two
bytes are allocated for the line number, whether it is 1 or the
maximum value allowed, 63999. The only savings in memory comes
GOTO 10 being shortened to
Any single digit including 1 and even 0 could have been used
instead. Line number variation in the RUN
variants attests to its arbitrariness for function, demonstrating
that 10 was a line-numbering convention, but was not required. That
8 was both arbitrary and a specific departure from convention may
then suggest specific grist for interpretation. For a one-line
program that loops forever, it is perhaps appealing to number that
line 8, the endlessly looping shape of an infinity symbol turned
upon its side. However, whether the program is numbered 8 or 10,
the use of a number greater than 0 always signals that
8PRINT) is, like Barthes’s “work,” “a
fragment of substance,” partial with potential for more
to be inserted and with the potential to be extended (Barthes 1977,
Why are typed line numbers required at all in a BASIC program? Programs written today in C, Perl, Python, Ruby, and other languages don’t use line numbers as a language construct: they aren’t necessary in BASIC either, as demonstrated by QBasic and Visual Basic, which don’t require them. If one wants a program to branch to a particular statement, the language can simply allow a label to be attached to the target line instead of a line number. Where line numbers particularly helped was in the act of editing a program, particularly when using a line editor or without access to a scrolling full-screen editor. The Commodore 64 does allow limited screen editing when programming in BASIC: the arrow keys can be used to move the cursor to any visible line, that line can be edited, and the new version of the line can be saved by pressing RETURN. This is a better editing capability than comes standard on the Apple II, but there is still no scrollback (no ability to go back past the current beginning of the screen) in BASIC on the Commodore 64. Line numbers provide a convenient way to get back to an earlier part of the program and to list a particular line or range of lines. Typing a line number by itself will delete the corresponding line, if one exists in memory. The interactive editing abilities that were based on line numbers were well represented even in very early versions of BASIC, including the first version of the BASIC that ran on the Dartmouth Time-Sharing System. Line numbers thus represent not just an organizational scheme, but also an interactive affordance developed in a particular context.
The space between the line number 10 and the keyword
function exactly as the standard
with spaces does. The spaces are of course helpful to the person
trying to type in this line of code correctly: they make it more
legible and more understandable.
Even in this exceedingly short program, which has no variables (and
thus no variable names) and no comments, the presence of these
optional spaces indicates some concern for the people who will deal
with this code, rather than merely the machine that will process
it. Spaces acknowledge that the code is both something to be
automatically translated to machine instructions and something to
be read, understood, and potentially modified and built upon by
human programmers. The same acknowledgment is seen in the way that
the keywords are presented in their canonical form. Instead
? could be used instead, and there are Commodore-specific
two-character abbreviations that allow the other keywords to be
entered quickly (e.g.,
GOTOcan typed as G followed by SHIFTO.) Still, for clarity, the longer (but
easier-to-read) version of these keywords is shown in this program,
as it is in printed variants.
PRINT “HELLOWORLD” the
output of the statement is simply the string literal,
the text between double quotes. The string in the maze-generating
program is generated by a function, and the output of each
When BASIC was first developed in 1964 at Dartmouth College,
however, the physical interface was different. Remarkably, the
language was designed for college students to use in interactive
sessions, so that they would not have to submit batch jobs on punch
cards as was common at the time. However, the users and programmers
at Dartmouth worked not at screens but at print terminals,
initially Teletypes. A
This function takes a numeric code and returns the corresponding character, which may be a digit, a letter, a punctuation mark, a space, or a “character graphic,” a nontypographical tile typically displayed alongside others to create an image. The standard numerical representation of characters in the 1980s, still in wide use today, is ASCII (the American Standard Code for Information Interchange), a seven-bit code that represents 128 characters. On the Commodore 64 and previous Commodore computers, this representation was extended, as it often was in different ways on different systems. In extensions to ASCII, the other 128 numbers that can be represented in eight bits are used for character graphics and other symbols.
The Commodore 64’s character set, which had been used previously on the Commodore PET, was nicknamed PETSCII.
The complement to
CHR$ is the function
which takes a quoted character and returns the corresponding
numeric value. A user who is curious about the numeric value of a
particular character, such as the capital letter A, can type
see the result, 65. A program can also use
to convert a character to a numeric representation, perform
arithmetic on the number that results, and then convert the new
number back to a character using
In lowercase mode, this can be used to shift character between
uppercase and lowercase, or this sort of manipulation might be used
to implement a substitution cipher.
Character graphics exist as special tiles that are more graphical than typographical, more like elements of a mosaic than like pieces of type to be composed on a press. That is, they are mainly intended to be assembled into larger graphical images rather than “typeset” or placed alongside letters, digits, and punctuation. But these special tiles do exist in a typographical framework: a textual system, built on top of a bitmapped graphic display, is reused for graphical purposes. This type of abstraction may not be a smooth, clean way of accomplishing new capabilities, but it represents a rather typical way in which a system, adapted for a new, particular purpose, can be retrofitted to do something else.
RND are both functions, so the keyword is followed in both cases by an
argument in parentheses.
ends with the dollar sign to indicate that it is a string function
(it takes a numeric argument and returns a string), while
RND does not, since it is an arithmetic function (it takes a numeric
argument and returns a number). The parentheses here also make
clear the order of arithmetic operations. For instance,
RND(1-2) is the same as
RND(1)-2 is two subtracted from the whatever value is returned by
All math in Commodore BASIC is done on floating point numbers (numbers with decimal places). When an integer result is needed (as it is in the case of CHR$), the conversion is done by BASIC automatically. If this value, 205.5, were to be converted into an integer directly, it would be truncated (rounded down) to become 205. If more than 0.5 and less than 1 is added to 205.5, the integer result will be 206.
This means the character printed will either be the one corresponding to 205 or the one corresponding to 206: ∖ or ∕. A quirk of the Commodore 64 character set is that these two characters, and a run of several character graphics, have two numeric representations. Characters 109 and 110 duplicate 205 and 206, meaning that 109.5 could replace 205.5 in this program and the identical output would be produced.
This symbol indicates addition, of course. It is less obvious that
this is the addition of two floating point numbers with a floating
point result; Commodore 64 BASIC always treats numbers as floating
point values when it does arithmetic. The first number to be added
is 205.5; the second is whatever value that
returns, a value that will be between 0 and 1. On the one hand,
because all arithmetic is done in floating point, figuring out a
simple 2 + 2 involves more number crunching and takes longer than
it would if integer arithmetic was used. On the other hand, the
universal use of floating point math means that an easy-to-apply,
one-size-fits-all mathematical operation is provided for the
programmer by BASIC. Whether the programmer wishes to add
temperatures, prices, tomato soup cans, or anything else,
“+” will work.
The mathematical symbol “+” originated, like “&,” as an abbreviation for “and.” As is still conventional on today’s computers, the Commodore 64 has a special “plus” or addition key but does not have any way to type a multiplication sign or a division sign. While they appear in some eight-bit codes that extend ASCII and in Unicode, the multiplication and division signs are absent from ASCII and from PETSCII. Instead, the asterisk (*) and the slash, virgule, or solidus (/) are used. Given the computer’s development as a machine for the manipulation of numbers, it is curious that typographical symbols have to be borrowed from their textual uses (“*” indicating a footnote, “/” a line break or a juxtaposition of terms) and pressed into service as mathematical symbols. But this has to do with the history of computer input devices, which in early days included teletypewriters, devices that were not originally made for mathematical communication.
This function returns a (more or less) random number, one which is between 0 and 1. The number returned is, more precisely, pseudorandom. While the sequence of numbers generated has no easily discernible pattern and is hard for a person to predict, it is actually the same sequence each time. This is not entirely a failing; the consistent quality of this “random” output allows other programs to be tested time and time again by a programmer and for their output to be compared for consistency.
It is convenient that the number is always between 0 and 1; this allows it to easily be multiplied by another value and scaled to a different range. If one wishes to pick between two options at random, however, one can also simply test the random value to see if it is greater than 0.5. Or, as is done in this program, one can add 205.5 and convert to an integer so that 205 is produced with probability 0.5 and 206 with probability 0.5.
More can be said about randomness, and much more is said in the chapter on the topic.
RNDis given any positive value (such as this 1) as an argument, it produces a
number using the current seed. This means that when
is invoked immediately after startup, or before any other
it will always produce the same result: 0.185564016. The next
invocation will also be the same, no matter which Commodore 64 is
used or at what time, and the next will be the same, too. Since the
sequence is deterministic, the pattern produced by the
10 PRINT program, when run before any other invocation of
RND, is a complex-looking one that is always the same.
Using a semicolon after a string in a
The colon separates two BASIC statements that could have been placed on different lines. In a program like this on the original Dartmouth version of BASIC, each statement would have to be on its own line, since, to keep programs clear and uncluttered, only a single statement per line is allowed. The colon was introduced by Microsoft, the leading developer of microcomputer BASIC interpreters, as one of several moves to allow more code to be packed onto home computers.
This is an unconditional branch to the line
indicated—the program’s only
line, line 10. The
keyword and line number function here to return control to an
earlier point, causing the first statement to be executed
endlessly, or at least until the program is interrupted, either by
a user pressing the STOP key or by shutting off the
although not original to BASIC, came to be very strongly associated
with BASIC. A denunciation of
is possibly the most-discussed document in the history of
programming languages; this letter (discussed in the
“Regularity” chapter) plays an
important part in the move from unstructured high-level languages
such as BASIC to structured languages such as ALGOL, Pascal, Ada,
and today’s object-oriented programming
languages, which incorporate the control structures and principles
of these languages.
Once a BASIC program is entered into the Commodore 64, it is set
into motion, executed, by the
is typed, the program
lies dormant, full of potential but inert.
is therefore an essential token yet is not itself part of the
is what is needed to actualize the program.
In a similar fashion, describing the purpose of each of the twelve
address the underlying complexity of the program. A token-by-token
explanation is like a clumsy translation from BASIC into English,
naively hewing to a literal interpretation of every single
character. Translation can happen this way, of course, but it
glosses over nuance, ambiguity, and most important, the cultural,
computational, and historical depth hidden within this one line of
code. Plumbing those depths is precisely the goal of the rest of
this book. The rest of this book is the
to the introduction here. So, as the Commodore 64 says . .
PLAN OF THE BOOK
The more general discussions in this book are organized in five
chapters and a conclusion. Preceding each of the five chapters and
before the conclusion are six
“remarks.” These are more specific
discussions of particular computer programs directly related
they are programs that the authors have found or (in the spirit of
early Commodore 64 BASIC programmers, who were encouraged to
modify, port, and elaborate code and who often did so) ones that
the authors have developed to shed light on how
works. These remarks are indicated with
“REM” to refer to the BASIC
statement of that name, one that allows programmers to use a line
of a program to write a remark or comment, such as
55 REM START OFMAINLOOP.
The first chapter, Mazes, offers the cultural context for reading a
maze pattern in 1982. The chapter plumbs cultural and scientific
associations with the maze and some of the history of mazes in
computing as well. Regularity, the second chapter, considers the
that repeat in space, in time, and in the
program’s flow of control. The aesthetic and
computational nature of repetition is discussed as well as the
interplay between regularity and randomness. The third chapter,
Randomness, offers a look at cultural uses and understandings of
randomness and chance, as they are generated in games, by artists,
and in simulations. It aims to show that behind a simple, commonly used capability of the computer
lie numerous historical associations and uses, from the playful to
the extraordinarily violent. BASIC, the fourth chapter, explains
the origins of BASIC and describes how this language came to home
computing. The ways in which short BASIC programs were circulated
is also discussed. The fifth chapter, The Commodore 64, delves into
the computer’s history, exploring the machine on
runs. The most relevant technical topics, including the PETSCII
character set, the VIC-II video chip, and the KERNAL (the Commodore
64’s operating system, stored in 8K of ROM) are
also discussed. This chapter situates
in the context of its platform and that
platform’s rich cultural contexts.
The remarks reflect on a series of slight variations in the
original BASIC program, all of which are also in Commodore 64
BASIC; on ports of
to different languages and computers; on several ports and
the Processing platform; on a collection of one-liners, including
some Commodore 64 BASIC one-liners found in early 1980s print
sources; on an Atari VCS port of the program; and on some greatly
elaborated versions of the program in Commodore 64 BASIC. The last
remark includes elaborations that generate stable full-screen
mazes, allow a user to navigate a symbol around those mazes, and
test those generated mazes for solubility.
One line of code gives rise here to an assemblage of readings by
ten authors, offering a hint of what the future could
hold—should personal computers once again invite
novice programmers to