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 SENTEND' imperitive 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 terminiating
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.