What I learned in college because I had to use mainframes
Andy Lester's got a great article over at the New Relic site which makes me realize how lucky I was in college.
I graduated in 1979; our computing platform was a 360/75, late upgraded to a 370/145 (I think) still running OS/360 in a VM under VM/360. This meant that for our own projects, we actually ended up doing a number of the things that Andy talks about as a matter of survival.
We did not have a version control system at all; we ended up using generation data sets and meticulous tape backups to manage our source code. A tool that just made that work would have been a miracle. (I remember well having to write and use programs to recover "deleted" partitioned data set members when one realized that it would have been a good idea to back that member up but didn't.)
We did indeed learn to write in the "weeder" class, assembly language programming. It had a professor who had a very specific idea as to what was good style and what was not - and a meaningful comment on every instruction was a key part of that style. One learned to write a good description of the algorithm one was implementing in the comments, as each "bad" or missing comment was 5% off your grade!
We didn't have full-up Perl style regular expressions in every language, but there was SNOBOL, with its first cut at a regular-expression driven language, and a few interesting wrinkles that Perl doesn't have. That was an eye-opening experience into just how powerful regular expressions were, and SNOBOL remained my go-to text and data munging language until I left mainframes.
Understanding libraries was key when one was writing primarily in assembler (it was fastest to compile and used the least resources to run, very important on a not-very-large timeshared machine); the more code you could reuse, whether IBM's or someone else's, the less time you spent waiting for a job to turn around and come back, so building libraries (both macro libraries - sequences of configurable assembler code that expanded inline - and binaries) was key to becoming productive and staying that way, simply because the more code you had that you didn't have to debug each time, the less time you wasted on waiting around for runs to finish. This also explained why a lot of us became nocturnal and adept at finding our way into locked buildings overnight - no one else was running anything on the machine then; if you could find a terminal after 9 PM, you got nearly instant turnaround on jobs.
The first implementations of SQL available for IBM mainframes weren't out until after 1979, and those were quite expensive. I was working at NASA, infamous for having absolutely no money, so SQL databases weren't something we had for quite a while, and even then they were limited to very specific projects. A miss on that one, and definitely something that held me back somewhat until my current job, where I've really had to learn to use it well.
Tools were few and far between in 1979; editing was via WYLBUR, a line-oriented editor. Still very important to learn how to use it well, when the maximum speed you were getting out of your terminal was 30 characters per second (or 11, if you were on a Selectric terminal). Not knowing how to do global changes and finds would mean either sending your file to print, waiting for the turnaround, and then hand-editing, or many, many 'list' commands, and failed jobs because you missed a change you needed to make.
Assembler was fantastic for teaching defensive programming because almost nothing could be taken for granted. If you needed bounds checking, exception handling, error checking, anything - you had to code it. As an object lesson, there were some very interesting, and exploitable, bugs in OS/360 caused by bad bounds checking in the logical equivalent of system calls, like the one that took an offset into a dispatch table to call code in privileged mode - but didn't verify that the offset was actually valid...
I very, very luckily fell in with some very talented programmers; simply because the programming environment was so primitive, we were impelled to build a hack that would let us run a job and communicate to it via a shared file - essentially we built a one-lung version of TSO to help get our work done faster.
We had to work with the existing conversational programming language implementation (CPS, a PL/1 variant adapted to be sort of like BASIC) to figure out how to make the connection between it and the batch job (we eventually ended up using a keyed-access dataset, using one record for the command line, another for a "go-ahead/break" semaphore, and another for returning output from the batch job). This required us to work with what features we had available in CPS, as we couldn't extend it, and to collaborate to add and update features.
This was not a typical experience; I was astoundingly lucky to have had the caliber of classmates that I did, and as forgiving a systems group as we had. We were pretty sure that they had figured out we had created a clandestine time-sharing system, but they were kind enough to let us run it - and we were careful to not abuse their trust.
I remember the magic of the Selectric head spinning and stopping, spinning and stopping, with nobody at the keyboard -- although generally the "realtime" terminals up on the 3rd floor of Weil Hall at the University of Florida were available only to the "Management Information Sciences" majors in 1976.
Yes, the "typeball nod" so you knew your connection hadn't dropped. :)
My junior year I didn't yet have keys to the building (I got them senior year so I could have office hours for the business-school freshmen I was teaching FORTRAN - that never made sense to me either...), so we worked out the following: unlock a window in the terminal room. Climb onto the first-floor roof of the student services building. Cross that to the sciences building. Climb the ladder to the astronomy observing platform on the top of the building. Go in that door, down the hall, out the window onto the roof *again*, then in through the terminal room window.
Anything for more runs!
I was permanently scared by my use of the mainframe back in the early 70s. I still worry about squeezing every millisecond of performance out of my perl scripts. We had 16K of memory and 3 seconds for our programs to run. One typo on a punch card and you had to wait for 20 minutes to run your program again. God help you if you dropped your handful of cards. But it taught me patience, which was useful in other areas of life. Programmers of that era were all better-than-average parents.
An infinite loop timed out at 0.49 seconds of CPU time at the University of Florida, which was very bad news because we were allocated only a certain number of seconds per course.