Inside COBOL #09
by Shawn M. Gordon
President S.M.Gordon & Associates
This month I am going to cover coding styles and standards. Unlike other people however, I am not going to tell you what is right and wrong. Over the years I have looked at, re-writtten, and maintained a lot of different code by different people, and I have learned that so-called ‘structured’ coding techniques are more often than not, very difficult to maintain. This is mostly because people don’t really understand how to write structured code. I am not going to get into a discussion about structured code because I honestly think that the only structure that is important is a readable, workable structure. It really doesn’t matter if you use a GO TO statement if that makes the code easier and more straight forward to deal with.
First let’s talk about paragraph naming, and calling conventions. I once worked at a spot where the MIS Manager would use paragraph names like N-A-F-C-W, this was somehow supposed to convey the parantage of the paragraph, I found it impossible to trace so I came up with a standard naming convention. What I like to do is use an alpha character followed by a 4 digit number. The alpha character loosely had to do the type of code being done, but they were assigned in sequential order. So the ‘A’ series would typically be start up and initialization stuff, the B series would typically be called from the A series to perform the longer logic constructs, the D series was data base call’s (I have since changed those to macros), E was for called error routines, F was file loading and manipulation, etc. Now A, B, and C really depended on what kind of program it was, but this style made it pretty easy to locate a chunk of code without having to look for a paragraph name like ‘READ-MY-FILE’.
Now you know what I do for paragraph names, but how about calling them? This is probably my biggest pet peave because a lot of people like to do this in the name of ‘structured’ programming. That is to have a zillion levels of nested perform statements, so you have something like having paragraph one call paragraph two which calls paragraph three, etc. I have seen this easily go out seven or more levels. You know how long it takes to break this apart, especially if you aren’t familiar with the code, or worse yet, you use straight english paragraph names that give no indication of where in the code they are? This coding style is very popular in the C language, which is probably why C get’s on my nerves for business applications.
Here is one of the more obnoxious examples that I run into all the time. It has to do with one of the most common operations, reading a file. Here is an example of what I usually see, and then an example of how I would make it easier to read.
01 EOF-INDICATOR PIC X VALUE SPACES. 88 EOF-FLAG VALUE 'Y'. PROCEDURE DIVISION. HOUSEKEEPING. OPEN INPUT MYFILE. PERFORM READ-FILE UNTIL EOF-FLAG. READ-FILE. READ MYFILE AT END MOVE 'Y' TO EOF-INDICATOR. IF NOT EOF-FLAG * do all your processing under this IF statement.
Now using the same scenario here are two ways to make it more readable. The first example is better if you need multiple reasons for getting out of the paragraph. The second is good if the processing required on the record you read is fairly minimal.
<<<< FIRST EXAMPLE <;><;> PROCEDURE DIVISION. A1000-INIT. OPEN INPUT MYFILE. PERFORM A1100-READ THRU A1100-EXIT. A1100-READ. READ MYFILE AT END GO TO A1100-EXIT. * do all your processing here. A1100-EXIT. EXIT. <<<< SECOND EXAMPLE <;><;> 01 EOF-INDICATOR PIC X VALUE SPACES. 88 EOF-FLAG VALUE 'Y'. PROCEDURE DIVISION. A1000-INIT. OPEN INPUT MYFILE. PERFORM UNTIL EOF-FLAG READ MYFILE AT END SET EOF-FLAG TO TRUE NOT AT END * do processing here END-READ END-PERFORM.
You’ll notice that the use of the ‘GO TO’ statement actually makes the first example easier to read. This is a great use of ‘GO TO’ and I really don’t think it sacrifices anything. I got into the habit of using ‘GO TO’ in interesting ways because I had a programming boss once that wouldn’t let us use ‘VARYING’ on the ‘PERFORM’ statement for some strange sick reason that he never bothered to explain. At least it showed me that ‘GO TO’ isn’t the son of satan, and can be used without cosmic consequences.
Let me issue a warning on the use of GO TO however. You have to make sure that you don’t ‘GO TO’ out of a paragraph that you performed because you can eventually blow your STACK. Here is an example of the error message you will get if you do happen to exceed this parameter.
‘Return at end of Procedure #6 To progname+$1690 stmt #501’
The second example has two interesting points. The first is that we have made the file processing an ‘inline’ perform making use of the ‘AT END’ and ‘NOT AT END’ directives on the read. The second thing we have done is made the use of the 88 level item ‘EOF-FLAG’ very intuitive by setting it to ‘TRUE’ instead of manipulating the 01 level item which can be very difficult to follow.
Here’s another tip for you. You know how everyone tell’s you to document everything? We all hate to do it, but after you have tried to puzzle out what you were doing in a program once or twice you will probably start doing it on a regular basis. What I have found is that a good decent overview of what the program does written at the top of the program is always helpful. Then inside the program itself a little description at the top of any paragraph that isn’t REALLY obvious. The name of the paragraph should cover documentation for the obvious stuff. If you are doing something complex with simple variable names, then a little map will certainly help move things along. Now here is something that will probably shock you, you can actually go overboard on documentation. That’s right, you can actually put to much documentation into a program. At a certain point it start’s to become very difficult to read the code because someone has put comments on just about every line of code. This happens, believe me, I have had to wade through thousands of over documented lines of code, and I have to wonder how much time was wasted putting in all these nicely formatted “$PAGE” statements in front of every single paragraph. Moderation in all things.
Ok, next topic, alignment of variable declarations and code statements. This is a real personal area, so just give a thought to what I have to say, but don’t get upset if I step on your personal coding style. I have found that simple alignment of variable declarations and initialization goes a long way to making a program more readable, for example;
01 CUST-NUMBER PIC X(6) VALUE SPACES. 01 CUST-NAME PIC X(30) VALUE SPACES. This kind of thing is hard to read, however this example is much easier; 01 CUST-NUMBER PIC X(06) VALUE SPACES. 01 CUST-NAME PIC X(30) VALUE SPACES.
I have also found that for single character declarations it’s actually easier to read as ‘PIC X’ instead of ‘PIC X(01)’, not to mention easier to type. This actually brings up an interesting point about variable declarations. Did you know that on the Spectrum machines that variables that are used to call Image data base routines, or system intrinsics must be 32 bit aligned? Do you know the only way to guarantee 32 bit alignment? You have declare the variable as an 01 or 77 level (the 77 level variable is in the process of being obsoleted). So if you are getting some really weird problems in some program, try changing some of your variable declarations around, it’s worked for me.
I have seen people go overboard with spacing and alignment in the PROCEDURE DIVISION to a point where it becomes very hard to read. The two main things that I worry about is PERFORM and MOVE,
PERFORM A1100-READ THRU A1100-EXIT MOVE WS-CUST TO CM-CUST.
Kind of like that, I don’t bother with moving the IF statement all over the place, other than to line up the conditions if they span multiple lines. There are little things I like to do with READ and OPEN statements, but that isn’t that big of a deal.
Now what about nested if statements? Here are my least favorite examples that I run into all the time. The second one is actually considered to be good coding practice, but I don’t really care for it from an aesthetic point of view.
IF statement code IF statement code IF statement code ELSE NEXT SENTENCE ELSE NEXT SENTENCE ELSE NEXT SENTENCE.
Pretty obnoxious huh? I see that kind of thing all the time. You know that the ‘NEXT SENTENCE’ imperative has basically been replaced with ‘CONTINUE’. Here is a COBOL 85 example of basically the same thing.
IF statement code IF statement code IF statement code END-IF END-IF END-IF.
In my opinion this can just make the code long and hard to read if there is enough statements in there. How about just terminating the whole with a period and getting it over with?
IF statement code IF statement code IF statement code.
Hopefully I didn’t upset anyone with my opinions on coding. To wrap up this month here is an interesting tidbit for you to try and find out. Do you know what a 66 level variable declaration is for? Have you ever used one? Do you know how to use it? I know what they are, but I have never had the occasion to use one, and I would love to see an example of it from someone.