It looks like you're new here. If you want to get involved, click one of these buttons!
In July 1973 DEC published 101 BASIC Computer Games, edited by David H. Ahl: the Wikipedia article has more about how this book was the basis for a famous collection of microcomputer BASIC programs. I’ve never found even a scan of the first or second printing of the book. The third printing from March 1975 is the one I own and is available for browsing or download as an e-book at the Internet Archive.
On pp. 169–171 there are two programs, POETRY and POET, that particularly fascinate me. I’ll focus here on the shorter one, POET, found on p. 171. Here is a transcription of the program as it was presented on that page:
90 RANDOMIZE
100 IF I<>1 THEN 101 ELSE PRINT "MIDNIGHT DREARY";
101 IF I<>2 THEN 102 ELSE PRINT "FIREY EYES";
102 IF I<>3 THEN 103 ELSE PRINT "BIRD OR FIEND";
103 IF I<>4 THEN 104 ELSE PRINT "THING OF EVIL";
104 IF I<>5 THEN 210 ELSE PRINT "PROPHET";
105 GOTO 210
110 IF I<>1 THEN 111 ELSE PRINT "BEGUILING ME";
111 IF I<>2 THEN 112 ELSE PRINT "THRILLED ME";
112 IF I<>3 THEN 113 ELSE PRINT "STILL SITTING..."\GOTO 212
113 IF I<>4 THEN 114 ELSE PRINT "BURNED. "\GOTO 212
114 IF I<>5 THEN 210 ELSE PRINT "NEVER FLITTING";
115 GOTO 210
120 IF I<>1 THEN 121 ELSE IF U=0 THEN 210 ELSE PRINT "SIGN OF PARTING";
121 IF I<>2 THEN 122 ELSE PRINT "AND MY SOUL";
122 IF I<>3 THEN 123 ELSE PRINT "DARKNESS THERE";
123 IF I<>4 THEN 124 ELSE PRINT "SHALL BE LIFTED";
124 IF I<>5 THEN 210 ELSE PRINT "QUOTH THE RAVEN";
125 GOTO 210
130 IF I<>1 THEN 131 ELSE PRINT "NOTHING MORE";
131 IF I<>2 THEN 132 ELSE PRINT "YET AGAIN";
132 IF I<>3 THEN 133 ELSE PRINT "SLOWLY CREEPING";
133 IF I<>4 THEN 134 ELSE PRINT "...NEVERMORE";
134 IF I<>5 THEN 210 ELSE PRINT "EVERMORE.";
210 IF U=0 THEN 212 ELSE IF RND>.19 THEN 212 ELSE PRINT ",";\U=2
212 IF RND>.65 THEN 214 ELSE PRINT " ";\U=U+1\GOTO 215
214 PRINT\U=0
215 I=INT(5*RND+1)
220 J=J+1\K=K+1
230 IF U>0 THEN 240 ELSE IF INT(J/2)<>J/2 THEN 240 ELSE PRINT " ";
240 ON J GOTO 100,110,120,130,250
250 J=0\PRINT\IF K>20 THEN 270 ELSE GOTO 215
270 PRINT\U=0\K=0\GOTO 110
999 END
I found two transcriptions of the program online (one from the book, one from a collection of BASIC programs that was digitally distributed) and compared them to develop this one, which I hope is character-for-character accurate.
You can see an image of the the code and sample output on the Internet Archive. It’s on the recto of that page spread.
The transcribed code of POET will not run on any contemporary BASIC interpreter I’ve found, even RetroBASIC, which is being developed to run the programs in 101 BASIC Computer Games among other BASIC programs. (The RetroBASIC developer provided one of two versions of the transcribed code.) Please let me know if I’m mistaken about RetroBASIC or if you find another native BASIC interpreter that will work.
Given this, I decided to port the program to Yabasic, which runs very nicely on Linux and is supposed to run on Macs as well.
10 REM This is POET from Ahl, David H., ed., 101 BASIC Computer Games,
20 REM 3rd printing., Digital Equipment Corporattion, 1975, p. 171
30 REM Ported to Yabasic by Nick Montfort, 2026-01-11
40 REM See https://github.com/maurymarkowitz/101-BASIC-Computer-Games/blob/main/poet.bas
50 REM As well as Bertram, Lillian-Yvonne and Nick Montfort, eds.,
60 REM Output: An Anthology of Computer-Generated Text, 1953-2023,
70 REM MIT Press, 2024, pp. 157-158
80 REM --
90 I=INT(5*RAN()+1) : U=0 : J=0 : K=0
100 IF I==1 PRINT "MIDNIGHT DREARY";
101 IF I==2 PRINT "FIERY EYES";
102 IF I==3 PRINT "BIRD OR FIEND";
103 IF I==4 PRINT "THING OF EVIL";
104 IF I==5 PRINT "PROPHET";
105 GOTO 210
110 IF I==1 PRINT "BEGUILING ME";
111 IF I==2 PRINT "THRILLED ME";
112 IF I==3 PRINT "STILL SITTING..." : GOTO 212
113 IF I==4 PRINT "BURNED. " : GOTO 212
114 IF I==5 PRINT "NEVER FLITTING";
115 GOTO 210
120 IF I==1 THEN IF U==0 THEN GOTO 210 ELSE PRINT "SIGN OF PARTING"; FI : FI
121 IF I==2 PRINT "AND MY SOUL";
122 IF I==3 PRINT "DARKNESS THERE";
123 IF I==4 PRINT "SHALL BE LIFTED";
124 IF I==5 PRINT "QUOTH THE RAVEN";
125 GOTO 210
130 IF I==1 PRINT "NOTHING MORE";
131 IF I==2 PRINT "YET AGAIN";
132 IF I==3 PRINT "SLOWLY CREEPING";
133 IF I==4 PRINT "...NEVERMORE";
134 IF I==5 PRINT "EVERMORE.";
210 IF (U>0 AND RAN()<.19) PRINT ","; : U=2
212 IF RAN()<.65 PRINT " "; : U=U+1 : GOTO 215
214 PRINT : U=0
215 I=INT(5*RAN()+1)
220 J=J+1 : K=K+1
230 IF (U==0 AND INT(J/2)==J/2) PRINT " ";
240 ON J GOTO 100, 110, 120, 130, 250
250 J=0 : PRINT : IF K<20 GOTO 215
270 PRINT : U=0 : K=0 : GOTO 110
999 END
The program of course has bits of Poe’s “The Raven” as a source text, but also uses a technique that relates to a traditional one, the cento, and an avant-garde one, the cut-up method.
On p. 169 of the book programmers are explicitly invited to modify POET and use different textual sources: “Try it with phrases from computer technology, from love and romance, from four-year-old children, or from some other subject. Send us the output[.]”
Despite the book being called 101 BASIC Computer Games, many of the programs — including POET — were not games in the standard sense. They were instances of “recreational computing.” Perhaps we still don’t have a good term for this category?
POET: “Original author unknown. Modified and reworked by Jim Bailey, Peggy Ewing, and Dave Ahl of DIGITAL.” p. 169.
I developed this port in about an hour and hope (but am not sure) that it functions just as the earlier program did.
One change I made, consistent with an editorial decision Lillian-Yvonne and I made in Output, was correcting the spelling of the word “fiery.” Many sorts of texts have typos and misspellings that should be corrected in a reading edition. We didn’t think maintaining the incorrect spelling was important to the vernacular nature of this program.
I also made many changes to the specifics of how the code functions. For instance, inequalities have been changed to equalities when testing different cases. I did this, in part, to maintain a 1-to-1 correspondence between the original lines (and their numbers) and the lines of the ported program. As with the translation of metrical verse, something must be given priority. In this case, not sound or sense, but the control flow or the “lineation” of the program.
I’m eager to hear comments on POET itself and on the work I’ve done to share it here. Also, try it with your own modifications and post the results!
Comments
Here’s a modification — I hope some of you have read the wonderful source text:
100 IF I==1 PRINT "halfway tree";
101 IF I==2 PRINT "there at midnight";
102 IF I==3 PRINT "ramshackle state";
103 IF I==4 PRINT "bitter! barren!";
104 IF I==5 PRINT "it make me frighten";
105 GOTO 210
110 IF I==1 PRINT "my mind";
111 IF I==2 PRINT "I reach down there";
112 IF I==3 PRINT "how to tell" : GOTO 212
113 IF I==4 PRINT "I found" : GOTO 212
114 IF I==5 PRINT "must and bound";
115 GOTO 210
120 IF I==1 THEN IF U==0 THEN GOTO 210 ELSE PRINT "contrary"; FI : FI
121 IF I==2 PRINT "mixed up";
122 IF I==3 PRINT "from the straight path";
123 IF I==4 PRINT "divded";
124 IF I==5 PRINT "is hard";
125 GOTO 210
130 IF I==1 PRINT "panic that did pitch";
131 IF I==2 PRINT "my heart’s core";
132 IF I==3 PRINT "attack me";
133 IF I==4 PRINT "sun beams sent";
134 IF I==5 PRINT "the mountain";
bitter! barren!
I reach down there is hard attack me
there at midnight
I found
from the straight path
sun beams sent
I reach down there ramshackle state
must and bound mixed up panic that did pitch
halfway tree must and bound, contrary sun beams sent,
it make me frighten
how to tell
from the straight path sun beams sent
it make me frighten, I found
contrary,
my heart’s core
@nickm Ah! Very good! One of the experiments I did with my son, and now teach standard when I teach high school classes on AI, is to train a Markov Model on The Raven:
https://leosstemhacks.wordpress.com/2018/08/22/raven-redux/
And in case anyone cares (which you actually shouldn't) here're the slides I use when I teach AI to high schoolers:
https://docs.google.com/presentation/d/1EmMDl-1RhTm6L8YYBvrygb1dio6hG3Znbv4hE_0mh_g/edit?usp=sharing
ps. David Ahl produced many followup volumes of these popular books. He tells me that they were the best selling computer books of their era (I don't recall whether he gave me a date range for that claim).
You're right that they contained much more than games, for example, check out pg. 20 of this 1984 edition (reproduced below for your convenience). There was a previous CCS reading workshop on this version of ELIZA. (I know that you know this Nick. Others might not, and might be interested in going back to look at it.)
(BTW, the header is incorrect. ELIZA wasn't originally written in Lisp -- long story for another time.)
https://mirrors.apple2.org.za/ftp.apple.asimov.net/documentation/programming/basic/Big Computer Games.pdf
Super interesting and to help with code annotation, I've set up a project here:
POET - code annotation of the CCS workbench
(You can log in with your email as a magic link, you don't need to use google or GitHub services)
And of course, in case you were wondering what that ELIZA redaction was and didn't have access to the book.
Yes, it's our very own @jshrager !
Okay, I plan to iterate this and did have some assitancd from Claude, but here is a remix, dedicated to @nickm , @jshrager , and @annettevee
Sources by group:
Sample output:
```
HAMURABI:, HOW MANY ACRES IS IT A RATS ATE
THINK OF AN ANIMAL YARDS TO GO PEOPLE STARVED, TOUCHDOWN
CHR$(205.5+RND(1)) DOES THAT SUGGEST PLEASE GO ON NEVERMORE
I love the sources, @markcmarino! I see the new line 90 says “ATARI BASIC,” but as with all text of this sort, that is just a high-probability text continuation. I’m not sure if this code runs in some Atari BASIC, but it doesn’t run on Yabasic.
If you simply replace the original strings in the Yabasic code with new strings, it would of course run.
It seems that using Claude is a very very complex (not to mention energy-intensive) process that results in non-code. (Or, more generously, code that has syntax errors.) Again, I’m not certain that it doesn’t run on any BASIC dialect. Maybe it will run on one that is harder to use these days and requires an Atari 8-bit machine or emulator?
@davidmberry, great seeing you in Paris and thanks for moving the code to the CCS Workbench. I couldn’t edit the main files there, and a few things need to be changed.
Most significantly, my first reply which has the string "halfway tree" on the first line is not a complete BASIC program. I just provided a range of lines that can be changed in the original program. To make it run, one would need to replace the ones in the original program with those.
And finally, @jshrager, the BASIC ELIZA (originating with your version) was clearly the most significant non-game in that book!
Thanks @nickm
I will update the code by hand. I had initially prompted the LLM with what I thought was a much more complex task: to put lines of BASIC into the PRINT statements that would remix and run. (And it also failed at that.) Prototyping ans testing with the LLM helped me come to the new idea for the piece, which I admit I could have done through simple string substitution, as I might with a custom Taroko Gorge.
Actually, your comment reminds me of something we may want to discuss: AI shaming, where we ding the AI for its failings (which at times are our failings at poor prompting) and shame the users for wasting energy and resources. (I don't mean that was your intent, just usung your comment to raise the discussion.)
What do we make of that aspect of contemporary code culture, especially in a world where programmers have so much pressure to use the tools for productivity? Or when others are still exploring the potential and limitations of these tools? What is its role if AI shaming in shaping how code is developed and discussed?
Actually I think I might call this Vibe-killing rather than AI shaming as a play on "killing the vibe," not because I think it is necessarily bad to do that.
I love the many layers and facets to POET as an example, and how they could fit into any or all of the three categories of the Software Heritage / UNESCO code and cultural heritage show that we are currently discussing, e.g.:
1) an early example of computer generated poetry that 2) circulated like folk art, in the broader context of 3) a popular and influential collection of basic programs (101 BASIC Computer Games) that was 4) widely ported adapted and reimplemented multiple times, and 5) demonstrated a broad definition of "games" and 'recreational computing' activities, art objects, and toys, all of which 6) were initially written in a mix of different BASIC dialects, presenting an archeological challenge as to what hardware emulation / OS / software stacks were necessary to make the original code run, and 7) for this very reason, the discourse that we find running from later editions of the book up through contemporary discussions forums and fan sites is all about constant need to emulate, recover, preserve, port, and reimplement -- a tension that was obviously evident to the original editor even back in the mid-1970s.
This can all lead out to larger questions from "how did computer users encounter early computational poetry?" to "what is a programming language, and what is a program?" (in the Ship-of-Theseus sense that we see with the myriad BASIC dialects and many possible versions of POET that could run on each of them).
Regarding "transcribed code of POET will not run on any contemporary BASIC interpreter I’ve found":
The specific issue of executing the original POET code also seems like a great paradigmatic example of a code / execution problem for a CCS researcher (and one that could then be applied to many of the examples of code behind the OUTPUT book artifacts we are also discussing in this working group). [Sigh -- although, on re-reading this sentence, I feel like "great paradigmatic example" follows the "effusive description + generalization" template that sycophantic LLMs have been barraging me with lately. Nevertheless, in this case I do actually mean it. Great. Paradigmatic. Example.]
We can trying to answer the question "what dialect of BASIC is this original code, and how did it originally run?" keeping in mind that a piece of BASIC code as-written may run on many versions of BASIC, or only a few versions, or only one, or none at all -- e.g. it contains transcriptions errors, or is napkin code that was never run et cetera.
There are three approaches that I initially considered. First: consult the books themselves. Second: Identify the code's unusual BASIC syntax features (the ones that cause it to fail on most common BASIC emulators, e.g. the drop-in basic web emulators available online) and align those features with the features of a known BASIC language. Third: try to trace early discussions of running either
POET.basspecifically or works from the 101 Basic Computer Games collection generally and see if they discuss canonical early places where we know the code was written, edited, or run, and what BASIC it was run on. These approaches converge on the same place.Possible tells in the code are the combination of:
RANDOMIZEcommand\character as a statement separator rather than e.g.:IF ... THEN ... ELSE IF ...syntax (specifically, the ability to parseELSE IFchaining)...and, because these features are unusual, especially when taken together, they are also the features that throw errors in many other common BASICs. For example, Joshua Bell's Applesoft BASIC in Javascript marks the
\characters with its syntax highlighter before the code is even run. In MSXPen, which emulates MSX BASIC v3.0 (1988), paste the code in the BASIC tab sidebar, press the RUN button, and typeRUNin the emulator window, and it fails on the first line (it doesn't like the RANDOMIZE command). The default BASIC emulator at 8bitworkshop gives errors such as(poet.bas @ 112) You can't do math on strings until they're converted to numbers.(it thinks the\statement separator is a math operator) and(poet.bas @ 210) The expression is incomplete.(it doesn't parseELSE IFas a valid construction). We can go on (e.g. loading the code into the PCjs DEC PDP-11 BASIC online emulator) and we will tend to see a subset of the same failure points in most BASIC dialects. When we then look up which BASIC dialect has all of these features....Conclusion: The original BASIC code dialect is probably DEC’s BASIC-PLUS-2 (aka BASIC+2 or BP2), a compiled BASIC installed on e.g. the PDP-11 RSTS/E -- and not to be confused with BASIC-PLUS (aka BASIC+) or with PDP-11 BASIC, and possibly(?) also not to be confused with the TOPS-20 BASIC-PLUS-2.
I'm actually not sure what the accessibility and preservation status is of DECs BASIC-PLUS-2 software for people who discuss wanting to find it, but it was a "layered product" that was originally sold separately by DEC as an add-on -- and like other "layered products" it is then not present in many PDP emulator setups by default, adding another layer of complexity to installing a working emulation stack. Still, conversations have happened at the conjunction of that 'stack' (PDP-11 + RSTS/E OS + BASIC-PLUS-2 + 101 BASIC Computer Games), perhaps because it is an interesting conjunction. Here is an example of detailed 2018 discussion thread on running the 101 BASIC Computer Games collection in PDP-11 emulation that digs into debates about which BASIC dialect(s) the code is written in and which version(s) it ran on:
From 1973(?) to 1975 to 1978 editions of the original book we are aware that this code was being constantly passed around amidst conditions of incompatibility and constant porting. We in the 2010s and 2020s may be further from the original 1970s hardware and interfaces, but we don't live in a fundamentally different relationship to BASIC dialects than the very first readers of 101 BASIC Computer Games -- some of the problems we immediately encountered above with the code were normal for them as well, and are already anticipated in part by disclaimers in the original DEC 1973 Preface to 101 BASIC Computer Games, appearing here in the 3rd edition:
While we are feeling the same pain, it is also just a bit funny how aggrieved David Ahl sounds five years later in his 1978 remake BASIC Computer Games: Microcomputer Edition when he explains how this normative state of affairs has driven him to reimplement every single program (including POET) in a single reference BASIC, Microsoft BASIC 4.0. From the section "The Basic Language" pg.x [TXT]:
So a constant companion to programs like POET from the beginning was being inspired, compelled, or abjured to just port, reverse engineer, or reimplement whatever didn't work. Draw a flowchart!
Still. I believe that it is possible to create a emulation setup as detailed in threads like these that runs the full original POET stack. We might admit that at some point this media archaeology challenge may become less investigative and more performative (or simply a fetish). But the pieces are there: The SIMH emulators for PDP-11 are available, in images with RSTS/E preinstalled, and there are archived versions of BASIC-PLUS-2, as well as discussions detail the installation procedures for various "101 Games" .dsk files [1] [2] [3] for different OS/storage setups.
That could be a recipe to run the original POET code, character-for-character, in one of its original environments.
Great sleuthing to find the particular BASIC of the 101 BASIC Computer Games program, @jeremydouglass. I assumed it was for a pre-1973 DEC BASIC, given that the program was “reworked” for a DEC publication in that year, but you seem to have found the specific dialect. With this information in hand, yes, it could certainly run on a contemporary computer. I was just stating that (as far as I knew) there was no BASIC interpreter for a contemporary computer that would directly run it, in a single step.
Regarding my textual / code editing of the program to port it to Yabasic, I wonder if doing so was a wise choice at all? Have any of you run the code in Yabasic? I changed things about the logic to maintain a 1-1 correspondence between the Yabasic lines and the lines of the 101 version. Perhaps I could have ported it to some entirely different programming language, not a BASIC at all, that most people have per-installed or that is available on the Web? That might have involved more extensive modification, but I’ve already deviated from the 101 program considerably, for instance by changing the testing of inequalities to test equalities. Did I just clutter things up by adding another “reworked” program, and one that no one other than me is going to use?
I keep wanting to write “the original program” in reference to the transcribed POET code from 101 BASIC Computer Games — but Ahl was careful to point out that this wasn’t the original code, the author of which was “unknown” (or forgotten).
On a different topic, I understand why you might characterize my response as “harshing your vibe,” @markcmarino. And I don’t want to discourage people from many different engagements with the program code. But even though I can’t offer a complete critique of vibecoding, I think it’s good to point out limitations and failures of the practice in specific cases. Programming without AI, I’d suggest, is good for when you are trying to understand something through the process of programming. If you just want to get some (easy to test) program working, perhaps there’s a different route to that. But I think a very, very large percentage of programming is actually done to understand rather than for instrumental purposes.
By the way @markcmarino, you may be interested to see this BASIC program, which generates other BASIC programs which generate texts:
This is the Applesoft BASIC code:
20DATAALL,WORK,AND,NO,PLAY,MAKES,NICK,A,DULL,BOY:FORI=0TO9:READA$(I):NEXT:?:?"1001 BASIC GAMES":?:FORI=0TO999:FORJ=0TO999:NEXT:?N$"DEAR READER:":?:?" 10 REM";:FORJ=0TO4:?" "A$(RND(1)*10);:NEXT:LIST:?:N$="NEXT, ":NEXT:?"LAST:":?:?" 0 GOTO
Some extra context:
David Ahl reprinted the POET source in an article for Creative Computing, volume 8, number 7 (July 1982) titled "Computer Poetry: Not So New". Ahl states POET was likely written by Jim Bailey (in contrast to 101, where Bailey is listed as one of a team that reworked the program). Ahl further states the original ran on the RSTS-11 timesharing system under Basic Plus.
I suspect the POET code was written in a different language originally. Or, alternatively, the programmers were heavily influenced by non-BASIC languages.
First, the logic relies on variables being initialized to zero. The code processes the first block of words until it gets to an actual initialization block on 210. This seems unnecessarily implicit logic-wise; why not jump to an actual entry point right after the
RANDOMIZEcall? Perhaps the original started by loading various strings into memory?Secondly, the negative logic in the
IFstatements, along with explicit goto-s, is unnecessary based on my reading of the BASIC manual. Line 100 could have been written as100 PRINT "MIDNIGHT DREARY" IF I=1or100 IF I=1 PRINT "MIDNIGHT DREARY". Instead, the style is reminiscent of assembly where some label is required for the branch.@nickm - Very good point that the DEC BASIC-PLUS-2 code is almost certainly not the "original."
@jwstarr - interesting find about the later 1982 article attributing the original (?) code to Jim Bailey.
@nickm - Re:
For me your Yabasic rework was very helpful as a model. Personally it didn't diminish my desire to also reimplement it myself, but it was useful once I found an quick online Yabasic emulator:
https://www.jdoodle.com/execute-yabasic-online
Then it was cut, paste, run.
However, that environment wasn't perfect for me -- it doesn't teletype the output the way that an original BASIC stack would, giving the visceral sense of the code running on screen more akin to the way it would on a line printer. Instead it just dumps many pages of text all at once until it hits the output character limit. So I tried a different online Yabasic emulator from Try It Online (TIO), Tio.run: Yabasic, which gave me a linkable code dump but errored out with
I poked at TIO a bit but didn't have the patience to get it working. My goal wasn't really to get things working in Yabasic specifically, but instead to adapt the code any accessible online BASIC execution environment that was sufficiently similar. I think this is a pedagogical habit--no matter how easy I try to make cross-platform installation for my students, the thing that really tries engagement is a web-based emulator that they can load on anything, even their phones or tablets, so that's always my first choice to "lower the barrier to entry." So instead of switching to a Yabasic desktop I went back to look at available online emulators that support a lot of different BASIC dialects and see which ones they support, e.g. 8bitworkshop. Unfortunately, it doesn't support support BASIC-PLUS-2 -- the closest you can get is BASIC-PLUS by adding the
OPTION DIALECT DECPLUSheader line. This gets us a bit closer.So like everyone else I had to modify it to get it working, but rather than a "remix" I tried to modify it as little as possible (in the spirit of shortest Levenshtein distance -- the minimum total number of modified characters). I made these minimal changes to backport the original syntax working to BASIC-PLUS:
\separators to the more common:.: IF _ ANDto keep the rest of the code aligned.In order to run it live in an online emulator: