Dan can be contacted at [email protected].
It was early 1977 and I was in the Atlanta IBM Education Center. I had come to Atlanta from Jacksonville, Florida, where I had spent almost a year as the Data Center Director for an insurance company's computer subsidiary. My boss had been convinced by IBM that our company should convert from the DOS/VS operating system that we were running on our IBM mainframe to OS/MVS. So far, so good. The gotcha' seemed to be that the nice-and-easy Job Control Language (JCL) that we used to run DOS jobs had to be converted to MVS JCL and we also had to recompile and reassemble all of our programs with the MVS version of the compilers and assemblers.
Before I get too far along, I should tell you that my basic belief about operating systems was that they were an inconvenience. We programmers had gotten along just fine without them and, it seemed to me, that operating systems were no more than IBM's way of collecting information that was none of their business. Further, I felt that DOS JCL, with as little as it did, was a nuisance. Every programmer that I knew had a box on their desk filled with generic DOS JCL cards. When you needed some JCL to test a program or print a tape, you just shuffled through the cards, grabbed what was needed, put them on the front and back of your card deck, and took it to the computer room. I now knew that the data center operators did the same thing. I also had the nagging suspicion that with OS JCL, things would never be the same again.
The fact that the class that I was attending was scheduled to last five days should have sounded an alarm about the degree of difficulty with OS JCL. I learned the Report Program Generator language (RPG) at a three day class. I learned COBOL at a four day class. It was only years later that I found out that the creator of OS JCL, Fred Brooks, called it the worst programming language ever invented -- and I was supposed to teach that language to the staff when I got home. Another clue about either JCL or the project to convert from DOS to MVS should have been the diversity of my fellow students. Typical IBM training is geared to a homogeneous audience. If it's a COBOL class, the students are programmers. If it's a DB2 class, the students are database administrators. As we went around the classroom for the obligatory self-introductions, I realized that some students were systems programmers, some were data center schedulers, two were application programmers, one student was an IS Director, and then there was me. As I remember, there were about a dozen students setting out together to learn OS JCL and not one of us really knew what we were getting into.
My classmates were of such a wide range of backgrounds because of the nature of the project, itself. It was to be a one-time endeavor and more than a few installations were using the process as a good excuse to make other changes. For our part, the company that I worked for used third-party software like sorts and print-spoolers and we intended to return to IBM utilities as part of our conversion. "You know", my boss said, "while we're going through all of the jobs, anyway, why not save some money?"
Who could argue?
After introducing ourselves to one another, the class began with our instructor telling us that there were only two JCL commands that were absolutely required to run a job: not surprisingly, the JOB command and the EXEC command. Well, I thought to myself, kinda' like DOS JCL.
Let me take a moment to describe DOS JCL -- and it will only take a moment. For instance, if I had written a program named DANPROG that read cards and wrote the data to an output tape, I would need some DOS JCL to execute the job. Like OS, all DOS JCL statements began with the double slash in columns 1 and 2 of the JCL card. In DOS, the slashes were followed by a space. First, there was a JOB statement and a typical DOS JOB statement, for me, was // JOB DAN. That was it for the JOB card. Since my program had a tape, I needed a TLBL statement. A typical TLBL statement looked like this: // TLBL DANTAPE. When the operator mounted the tape, he would place an ASSGN card in the deck to show which tape drive would have the output. Of course, there was an EXEC statement -- // EXEC DANPROG. When there was card input, the cards followed the EXEC statement and the last card in the entire deck was a card with /* in columns 1 and 2. Wrap a rubber band around the cards, give it to an operator, and go to lunch. There were additional, optional parameters that could be used and, for disk files, there were a pair of statements (DLBL and EXTENT) that could get tricky, but why bother? As I said earlier, things would never be the same with OS.
My hope that this new JCL might be like DOS JCL was quickly crushed. Let's once again take that simple JOB statement and my little program to read cards and write them to tape. Here's the new, improved, JOB statement:
//DANJOB JOB (Some Accounting Information),'Some Comment',CLASS=A,MSGCLASS=0, // MSGLEVEL=(1,1),NOTIFY=USERID
It took us all day to master the new JOB command. We left, at least the old timers did, whimpering. To encourage us, our instructor told us that on Tuesday we would learn about something called "data sets". A data set, he explained, could reside on any storage medium. I think I ordered a room service meal and went to bed early.
We would spend two days learning about the Data Definition (DD) command with which we could describe data sets. I discovered that the output tape from DANPROG now needed a DD command that looked like this:
//DANTAPE DD DSN=Something,DISP=(NEW,CATLG,DELETE), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=800,DSORG=PS)
The DSN (Data Set Name) parameter was for catalogued names. It seemed that we were going to have to replace our hand-logged tape file names with a new disk-resident tape catalogue. For disk files, the DD command was worse, much worse. We spent most of Wednesday talking about defining disk data sets.
By Thursday, I was reeling. Surely the EXEC command couldn't be complicated, I reasoned. And, at first blush, it seemed to be so:
//STEP01 EXEC PGM=DANPROG
What was the purpose of the PGM= parameter? I asked our instructor. To distinguish it from something called "cataloged procedures", he enthused. He was sure that cataloged procedures, where we created streams of JCL statements, loaded them to disk, and gave them a name; would be the real strength of our new installation. We talked about cataloged procedures on Friday.
If a student had an early Friday afternoon flight, he was to be excused early. Thankfully, my flight was in the mid-afternoon and I left our class, certificate of completion in hand, at our lunch break. This conversion was going to be a nightmare, I convinced myself and I wondered if there wasn't some way that I could get out of doing it.
In the years since 1977, a library of books has been written about OS JCL and college courses are still taught on the subject. For a decade, a prosperous cottage-industry arose around DOS-to-MVS conversions. Consultants got rich, systems were written to assist companies with the conversion effort, and small fortunes were made. But not for me. I spent the next six months teaching JCL, writing JCL, testing JCL, cajoling others to write JCL, cursing at JCL cards, and, finally, succeeding.
In the end, for programmers, it was still just a nuisance.