Introduction
From Maze
Jump to:
navigation
,
search
This wiki is a read-only archive; the page source is shown below.
= = Even those who have no interest in the playful, aesthetic, and educational dimensions of computing can no longer afford to ignore the cultural relevance of code. Computer programs not only function to process and display critical data, to facilitate communication, to monitor and report on sensor networks, and to shoot down incoming missiles -- they also have an existence as texts that are read by the original programmer, others who maintain and modify them, and in many cases wider and wider circles of meaning-seekers. We now live in a world where citizens examine the leaked source code that causes our voting machines to function. We find it unremarkable that particular snippets of code written for scientific projects are quoted in an attempt to demonstrate that climate change is a scam. It is no longer tenable to pretend that computer code is purely technical, without social, political, cultural, or other significant dimensions. Since computer code embeds stories (of a program's making, its purpose, the assumptions behind it, and so on), every symbol within a program can help to illuminate these stories and open historical and critical lines of inquiry. There are plenty of significant bodies of non-computational code that help to control lives but are not accessible to those they control: The code of law is a prime example. Although computer programs are "law" in a direct sense only to the computer, they control aspects of the world around us from the operation of toothbrushes, airplanes, and multinational corporations, embodying business, scientific, and governmental processes. Traditional wisdom might lead one to believe that "learning to read code" is monocultural, conservative chore. In the growing methodologies of Critical Code Studies, computer code may also be interpreted or approached through other means or perspectives. Source code is an entry point to much larger discussions about technology and culture. This book focuses on a single line of code, a BASIC program that simply reads: <nowiki>10 PRINT CHR$(205.5+RND(1)); : GOTO 10</nowiki> Although extremely concise, this program manages to represent fundamentals vital to interpreting a much broader class of programs. It acts as a gateway into the worlds of broader ideas and histories that are embedded within all sorts of computer code. = One Line = Unusually, this book focuses on a single line of code, a BASIC program with only two statements. Our understanding of cultural production, and of our culture overall, has been greatly advanced by studies that focus on a single work, such as Barthes’s ''S/Z,'' Beckett’s ''Proust,'' Arnheim’s ''Genesis of a Painting: Picasso’s Guernica,'' and Foucault’s ''Ceci n’est pas une pipe.'' These paintings and texts are significantly more complex than a one-line BASIC program, but the computer program is also more unusual and far less studied as a cultural artifact than are literary texts and paintings. There is much more to explain regarding its important contexts and its importance within and connections to our culture. By analyzing this short program from multiple viewpoints, the book explains how to read code deeply and shows the insights that come from doing so. Instead of discussing software merely as an abstract formulation, this book focuses on a specific program that exists in different printed variants and executes on a particular platform. Focusing on a particular line of code means that certain aspects of computer programs which have been overlooked in humanistic inquiry come to the foreground. Specifically, the focus on this one-line program highlights the nature of computer programs as variant and as seeds for learning, modification, and extension. The book also considers how the program engages with the cultural imagination of the maze, the history of regular repetition and randomness in computing, the story of the BASIC programming language and the specific nature of the Commodore 64. The eponymous program is treated as a distinct cultural artifact, but it also serves as a grain of sand in which a world is visible, a Rosetta Stone that gives us important access to the phenomenon of creative computing and the way computer programs exist in culture. = Ten Authors = The other major unusual feature of this book is that, although the book is mostly written in a single voice, it is written collaboratively by ten authors. This method of authorship shares some features with that used to write Wikipedia, although it differs from the writing of that encyclopedia in some significant ways, too. Our book was not written in public and was not open to anyone's edits; we gathered as a group after expressing interest in this program specifically during an online Critical Code Studies Workshop and, in a few cases, after being invited due to our interest in and publications on the study of code. While Wikipedia eschews "original research" for writing about facts which can be cited, our book is composed of scholarship, critical arguments, and original ideas about this program. We have included only those arguments and ideas that we find to some extent compelling and that we all essentially agree with. To produce a book-length discussion of 10 PRINT that situated the program in all of its relevant contexts and explained those contexts, it was clear that we would need to bring a rich variety of perspectives to bear. This book deals deeply with art history, the development of programming languages, the working of computation in general, the technical specifics of the Commodore 64 and related platforms, the material history of texts and the transmission of program in print, and many other topics. Given this range of related areas, it was sensible for us to share the background and fluency that we collectively have in these areas. Instead of isolating ourselves and writing ten articles, which surely would have produced significant overlaps and left significant gaps, we chose to attempt a new type of writing and to write what should appear, to the reader, as a book by a single author. Where it was necessary to write individually about personal experiences or perspectives that other authors do not share, we have included short singed notes that appear alongside the main text. = 10 PRINT CHR$(205.5+RND(1)); : GOTO 10 = By way of introducing this program, its output will be briefly described and its code will be explicated. The output of this program is the pattern shown on the endpapers of this book. 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. An initial explication of what each part of it does and means follows. == 10 == "10" is the only line number in this one-line program, and is probably the most conventional line number to use for the first line of any BASIC program. Most of the programs in the ''Commodore 64 User's Guide'' start with line 10, a choice which was typical in other books and on other platforms as well. Numbering lines in increments of 10, rather than simply as 1, 2, 3, ..., allows for 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. The standard version of BASIC for the Commodore 64, BASIC version 2 by Microsoft, made this sort of line numbering practice wise. There were some extensions to this BASIC which later provided a RENUMBER or RENUM command that would automatically redo the line numbering to 10, 20, 30, etc. 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, the RENUMBER was not provided with the version of BASIC that shipped on the Commodore 64. The variant of this program that appears in ''RUN'' uses 8 as its line number. This makes the program more concise in its textual representation, although it does not save any memory -- for each line of BASIC stored in RAM, two bytes are allocated for the line number, whether it is 1 or 63999 (the maximum value allowed). Of course, any single digit, including "1," could have been used instead. But for a program that loops forever, it is perhaps also appealing to have the one line numbered "8," an infinity sign turned on its side, a digit that suggests the potentially endless loop of the figure eight. Although "8" may offer us grist for interpretation, it is a departure from tradition and from standard line-numbering convention for a multi-line program. Mainly, the ''RUN'' program simply attests to the arbitrariness of the line number and that starting with 10 was a convention but was not required. Why are line numbers needed at all in a BASIC program? The programs written today in C, Perl, Python, Ruby, and other languages don't use line numbers, which actually aren't necessary in BASIC, as demonstrated by versions of BASIC including QBASIC and Visual Basic. If one wants the program to branch to a particular statement, a label can be attached instead of a line number. Where line numbers particularly help is in editing the 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 a line, the line can be edited, and pressing return saves the new version of the line. 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 C64. 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 line numbers allow were well-represented even in early versions of BASIC, including the first version of the BASIC that worked with the Dartmouth Time Sharing System. == {SPACE} == The space between "10" and "PRINT" is actually optional, as are all of the spaces in this program. If the line "10PRINTCHR$(205.5+RND(1));:GOTO10" is typed in instead, that program will function exactly as this one 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. Spaces acknowledge that the code is not only something to be automatically translated to machine instructions, but is also something to be read, understood, and potentially modified and built upon by human programmers. The same acknowledgment is seen in the way the keywords are presented in their canonical form: "?" could be used instead of PRINT, and there are two-character abbreviations that allow the other keywords to be entered quickly. But, for clarity, the longer but easier-to-read version of these keywords is shown in this version of the program, as it is in printed variants. == PRINT == This statement causes its argument to be displayed on the screen. The argument to PRINT can take a variety of forms, but here it is a string that is in many ways like the famous "HELLO WORLD." The string in this case is generated by a function and is only a single character long. This command is so well-known to us today that we may overlook that, as it is used here, it does not literally "print" anything in the way we normally use the word. To send output to a printer, PRINT has to be followed by "#" and the appropriate device number, then a comma, and then the argument that is to be printed. By default, without a device number, the output goes to the screen -- in the case of the Commodore 64, a television or composite video monitor. However, when BASIC was first developed in 1964 at Dartmouth College, 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. So a PRINT command that executed successfully did actually cause something to be printed. Although BASIC was less than 20 years old when a version of it was made for the Commodore 64, that version nevertheless has a residue of history, leftover terms from before a change in the standard output technology. Although video displays replaced scrolls of paper with printed output, the keyword PRINT remained. [The following paragraph should be moved into an appropriate chapter. -NM] The automatic scrolling behavior that PRINT accomplishes (shifting the text up when at the bottom of the screen by calling the KERNAL's CHROUT routine) points back to the print heritage of home computing. While the video display is 40 characters wide, the Commodore 64 maintains an 80-column line internally, which is why BASIC lines can be at most 80 characters. This 80-column logical line hearkens back to the 80-column line of the print terminal - which itself derives from the 80 columns on punched cards, which had been in use for decades before general-purpose computing. == CHR$ == 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 non-typographical 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, a 7-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 8 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 ASC, 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 PRINT ASC("A") and see the result, 65. A program can also use ASC 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 CHR$. 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, for instance. Character graphics exist as special tiles that are more graphical than typographical. That is, they are mainly intended to be assembled into larger graphical images rather than "typeset" or placed along 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 being 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. == ( == CHR$ and RND are both functions, so the keyword is followed in both cases by an argument in parentheses. CHR$ 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)," while "RND(1)-2" is two subtracted from the whatver value is returned by "RND(1)". == 205.5 == All math in Commodore BASIC is done on floating point numbers, number with decimal places. When an integer results 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) and would becomes 205. If more than .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: A left-leaning or right-leaning diagonal line. 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. == + == "+" here indicates addition, of course, but it's less obvious that this is the addition of two floating point numbers with a floating point result -- that is simply how Commodore 64 BASIC always works. The first number to be added is 205.5; the second is whatever value that RND returns, a value guaranteed to be between 0 and 1. Because all arithmetic is done in floating point, figuring out "2 + 2" is a much slower computation that it needs to be. 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 origin of this mathematical symbol is, 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 8-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. == RND == To a first approximation, this function returns a 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 nature 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 .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 .5 and 206 with probability .5. More can be said about randomness, and much more is said in the chapter on the topic. == 1 == When RND is given any positive value (such as this "1") as an argument, it produces a number using the current seed. This means that when RND(1) is invoked immediately after startup, or before any other invocation of RND, it will always produce the same result: .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 on that is always the same. == ; == Using a semicolon after a string in a PRINT statement causes the next string to be printed immediately after the previous one, without a newline or any spaces between them. The other options are the use of a comma, which moves to the next tab stop (10 spaces), or the use of no symbol at all, which causes a newline to be printed. Although this use of the semicolon from PRINT formatting was not original to BASIC, the semicolon was introduced very early on at Dartmouth, in version 2, a minor update that had only one other change. The semicolon here is enough to show that not only short computer programs like this one, but also the languages in which they are written, change over time. == : == The colon separates two BASIC statements which 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 was 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. == GOTO == This is an unconditional branch to the line indicated -- the program's only line, line 10. The GOTO keyword and line number functions like the JMP machine language instruction. In this case, it returns control to an earlier point, causing the first statement to be executed endlessly -- or at least until the program is somehow interrupted, either by the user pressing the STOP key or by the power being shut off. GOTO, although not original to BASIC, came to be very strongly associated with BASIC. A denunciation of GOTO is possibly the most-discussed document in the history of programming languages; it 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. = Plan of the Book = The more general discussions in this book are organized in five chapters and a conclusion. Before each of the five chapters and before the conclusion are six "Remarks." These are more specific discussion of particular computer programs that relate directly to 10 PRINT: They are programs that we 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) that we have developed that shed light on how 10 PRINT works. They are called "Remarks" in honor of BASIC's REM statement, which allowed programmers to use a line of a program to write a remark or comment. The first chapter, "Mazes," considers the many things that it might mean for a computer program to generate a maze pattern in 1982. The chapters plumbs the cultural associations with the maze, which has at various times been a terrifying and lethal threat, an upper-class outdoor amusement, and an instrument for behavioral science. The history of mazes in computing through the early 1980s is considered as well. "Regularity," the second chapter, considers the aspects of 10 PRINT that repeat in various ways: in space, in time, and in the program's flow of control. The aesthetic and computational nature of repetition is discussed, and some regular specifics of the Commodore 64 are described, so that the interplay between regularity and randomness, which is crucial to the program's interesting effect, can be understood. The third chapter, "Randomness," looks at how randomness or chance has been considered culturally -- from its use in games of chance, through its employment in the arts, and up to its use in simulation and science in recent decades. The chapter discusses how computers came to generate randomness (or, at least, approximations to it) and the ways in which the Commodore 64 generates randomness, including via the RND function that is used in 10 PRINT. "BASIC," the fourth chapter, explains the original development of BASIC in the context of programming languages and time-sharing. It continues to describe how BASIC came to home computing -- thanks largely to Microsoft, the company that developed the Commodore 64's version of BASIC. Some of the controversies within the hobbyist community and some of the complexities of Microsoft's early position and involvement are also discussed. The chapter concludes by describing two of the ways that short BASIC programs were often circulated: in print publications and (particularly in the case of interesting one-lines) by being memorized and later typed in. The fifth chapter, "The Commodore 64," describes the history and some of the important technical aspects of the very popular machine that 10 PRINT canonically runs on. Important aspects of Commodore's corporate history and of the computers that preceded the Commodore 64 are discussed, as is the home computer market and phenomenon in general. The KERNAL (the Commodore 64's operating system, stored in 8K of ROM) and its relationship to 10 PRINT is also discussed. [In all of these cases, there should be a statement about one or two of the most important arguments being made in each chapter -- not just what is discussed, etc. -Nick] The Remarks are on a port and elaboration of 10 PRINT in the language Processing by Casey Reas (co-creator of Processing); a collection of Commodore 64 BASIC one-liners found in early 1980s print sources; an assembly language demoscene production inspired by 10 PRINT and written by Ian Bogost, Stephane Hockenhull, and Nick Montfort; an array of variants and ports of 10 PRINT written by several of us and Warren Sack; and a greatly elaborated version of the program in Commodore 64 BASIC, by Michael Mateas, which generates stable full-screen mazes and tests them for solubility.
Views
Page
Discussion
View source
History
Personal tools
Log in / create account
Navigation
Main page
Recent changes
Help
Search
Toolbox
What links here
Special pages
Permanent link