MODULE 5 · LOOPS AND PROGRAM STRUCTURE · 6/7

GO TO and reading legacy code

15 min40 XPExercise

GO TO jumps to a paragraph and does not come back. Before COBOL-85 added inline PERFORM and END-IF, it was the only way to build many loops and branches, so programs written in the 1970s and 80s are full of it. You will not write new GO TOs, but you will certainly read them.

A loop built from GO TO

       IDENTIFICATION DIVISION.
       PROGRAM-ID. GOTODEMO.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-COUNT           PIC 9(2) VALUE ZERO.
       PROCEDURE DIVISION.
       0100-LOOP.
           ADD 1 TO WS-COUNT.
           DISPLAY "PASS " WS-COUNT.
           IF WS-COUNT < 3
               GO TO 0100-LOOP.
           DISPLAY "DONE".
           STOP RUN.

This prints PASS 01, PASS 02, PASS 03, DONE. Note the style: every statement ends with a full stop, and the IF has no END-IF. The full stop after GO TO 0100-LOOP is what ends the IF. That is typical of pre-85 code.

Why it is avoided

With PERFORM, every paragraph has one way in and one way out, and you can read the mainline to see the program's structure. With GO TO, any paragraph can be entered from anywhere, and to understand one paragraph you must search the whole program for every jump to it. The result is known as spaghetti code, and it is the main reason some legacy programs are feared.

There is a subtler danger too: a paragraph that is PERFORMed returns at its end. If code jumps out of a performed range with GO TO, the pending return is left behind and control can later return somewhere unexpected. That kind of bug can take days to find.

The accepted exception

Most shop standards allow exactly one use: GO TO the exit paragraph of a PERFORM ... THRU range, as you saw earlier. It never leaves the range, so the structure stays intact.

GO TO DEPENDING ON

Older code uses a computed jump as a switch statement:

       0100-DISPATCH.
           GO TO 0200-DEPOSIT 0300-WITHDRAWAL 0400-TRANSFER
               DEPENDING ON WS-TXN-TYPE.
           DISPLAY "UNKNOWN TYPE".
           GO TO 0900-END.

A value of 1 jumps to the first name, 2 to the second, and so on. Any other value falls through to the next statement. Today you would write EVALUATE WS-TXN-TYPE instead.

ALTER

If you ever see ALTER, it changes the target of a GO TO at run time. It was removed from the standard. Read the code very carefully and flag it for your team lead.

Refactoring GO TO code

To untangle a GO TO program:

  1. Find the loop: a GO TO that jumps backwards to an earlier paragraph. That becomes a PERFORM ... UNTIL. The condition that avoided the backward jump becomes the UNTIL.
  2. Find the branches: IF ... GO TO that skips forwards over some statements. That becomes IF ... ELSE ... END-IF.
  3. Put the read in its own paragraph and use the priming read shape.
  4. Run the old and new versions on the same input and compare the output line for line.

On the job

Do not refactor working production code just because it uses GO TO. Change what the ticket requires and match the existing style. A rewrite needs its own approval and full regression testing, because a program that has run nightly for 30 years has behaviours nobody documented.

Your task

The starter is a real-style legacy program: it reads sale amounts until 0 and pays commission at 5% on sales under 1000.00 and 8% on sales of 1000.00 or more. It works, but it is built entirely from GO TO.

Your team is adopting it into a modern codebase. Rewrite it with no GO TO, using the structured skeleton (priming read, PERFORM ... UNTIL, IF ... ELSE ... END-IF). The output must stay exactly the same:

SALE   500.00 COMMISSION    25.00
SALE  1000.00 COMMISSION    80.00
SALE  2499.99 COMMISSION   200.00
TOTAL COMMISSION     305.00

Run the starter first to see what it does. The tests pass for it already; only the no-GO-TO check fails.

fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.