In the fall of 1979 I was living in Rockville, Maryland. I had been accepted at the University of Maryland, but decided to attend Montgomery College, right up the street from my house, instead. I wasn’t ready for that huge, sprawling campus or the large and apparently impersonal classes.
I entered the computer science program, and took classes in the contemporary languages of that era. I learned Fortran IV in my first semester. Around the same time I started my first programming job, at a small Bethesda company called Moshman Associates. My first task there was to write a macro assembler for the 6502 microprocessor. I wrote a Fortran simulation of the hashing algorithm that we had planned to use for instructions and labels, found that it had an excessively high number of collisions, and was given a nice raise for my trouble.
In my second semester I took a class in PL/I programming. Designed by IBM, PL/I was a clean, structured, and relatively complex language. The compiler had many, many options for optimization and for diagnostic output. I spent a lot of time experimenting with the options and carefully inspecting the resulting printouts in an attempt to write the most efficient code possible.
I need to explain how we would write and run our code at that time. We didn’t have our own PCs and we didn’t have terminals to log in to a time-sharing system. Instead, we would use an IBM 029 card punch to punch each line of code into a punched card. The 029 was a complex mechanical device, with noises, rhythms, and so forth. The cards were assembled into a deck, preceded by some job control language (JCL) statements which provided a name for the job and instructed the computer how to set up input and out devices and how to compile and run the code. Small decks could be rubber-banded together for safekeeping; larger decks (usually for COBOL programs) were best kept in the cardboard boxes that originally held the blank, unpunched cards.
Once the deck was ready, I would walk up the hall to the job submission window, hand it in to the woman behind the counter, and she would stack it up in the card reader for eventual processing. At crunch times there would be line of students and a big pile of unprocessed jobs.
When it was my deck’s turn to be run, she would load it into the card reader, the computer would read and process the cards, and print the results on a very fast IBM printer. The attendant would take the printout, wrap it around the cards, and file it away until I came back to the window to collect the results.
On a good day the turnaround time would be about 3 to 4 hours. At crunch time it might take slightly longer. If all went well the printout would include two sections — the evidence of a successful compilation, and the results of actually running the program. I quickly learned to be careful with my code and with my algorithms, so that my code would compile and run after just a few iterations. Others were not so fortunate, and would spend many hours waiting for their results, only to find that they’d misplaced some punctuation, forgotten to declare a variable, or made an algorithmic mistake. I remember one of my fellow students “bragging” that “I am getting pretty good at this, it only took me 30 tries to get it to compile.”
I remember taking away a couple of things from these early experiences. First, there was great value in desk checking your code and your algorithms to increase the odds of a successful run. Second, it was good to have several projects going simultaneously to make the best of your your time. Third, I was always shocked (from reading my printouts) to see that my code could wait in the queue for several hours in order to be compiled and run in the space of 2 or 3 seconds.
As I mentioned earlier, the IBM line printer had a unique feature known as carriage control. By punching different special characters in the first column you could make the printer do some special things when it printed out your code. For example a “1″ would make it advance to the top of the next page of green bar paper before it would print. This was a good way to make sure that each function was on a page of its own. The “+” (plus) sign was magic; it would inhibit the printer from advancing the paper to the next line after printing. The next line would overstrike the current line.
I learned how to put it to very good use at the end of my PL/I class. The instructor asked us to make our final assignment look as pretty as possible. For most people this meant clean comments, good variable names, a clean structure, and so forth.
I decided to go a step further! Because this was a school, they would do their best to get as much use of each printer ribbon as possible. Instead of printing in a solid black color, the printer would usually produce text that was, at best, a medium gray. I did some experimenting, and found that 3 overstrikes would create nice, black text.
I decided to see if I could use the overprinting feature to make my final PL/I program look really nice. After getting my code to work as desired, I set out to use bold highlighting on all of the variable names. This turned out to be easy, although I spent a lot of time on the card punch. Here’s what I did.
First, before going any further, I should explain that PL/I used the characters /* to open a comment and */ to close one. The comments were free-form, and could flow from one card to the next as desired.
Let’s say that I was writing a simple loop. The actual, unadorned PL/I code and comment would look like this:
To make the MONTH variable bold I punched a series of cards like this:
The compiler saw a DO statement with a very long comment. The DO statement would look like this on the printout:
DO MONTH = 1 TO 12; /* PROCESS EACH MONTH */
The use of this irregular carriage control upset the otherwise rhythmic sounds made by the printer and the operators sometimes thought that the printer had jammed and would cancel the job. Once they realized that it was me (one benefit of going to a small school) they allowed it to run to completion.
Needless to say, I aced the class!
My PL/I knowledge turned out to be quite useful. Within a year I worked on a project for the National Science Foundation. I wrote a very cool program that would verify the accuracy of grant data, basically adding up the rows and columns to make sure that they matched in the application (an inverse spreadsheet). A year or two later I used Digital Research’s very capable PL/I-80 compiler to prototype some of my own ideas for a spreadsheet.
Note: I used Ralf Kloth’s Punchcard emulator to create the card images.