Loops with PERFORM

Control transfers to the paragraph (or section) and returns when it ends.

15.1 Out-of-line PERFORM

Control transfers to the paragraph (or section) and returns when it ends. THRU executes a range of paragraphs — traditionally paired with an EXIT paragraph:

PERFORM 2000-PROCESS-RECORD
           PERFORM 3000-CALC THRU 3000-CALC-EXIT
           PERFORM 4000-PRINT-HEADER 3 TIMES
3000-CALC.
           IF WS-AMOUNT = 0
               GO TO 3000-CALC-EXIT
           END-IF
           COMPUTE WS-RESULT = WS-TOTAL / WS-AMOUNT.
       3000-CALC-EXIT.
           EXIT.

15.2 PERFORM variants

Note: PERFORM ... UNTIL loops while the condition is false; it is a "do until", not "do while".

* Fixed count
           PERFORM 5 TIMES
               DISPLAY "Hello"
           END-PERFORM

      * Condition tested BEFORE each iteration (default)
           PERFORM UNTIL END-OF-FILE
               PERFORM 2100-READ-NEXT
           END-PERFORM

      * Condition tested AFTER each iteration (body runs at least once)
           PERFORM WITH TEST AFTER UNTIL WS-ANSWER = "N"
               DISPLAY "Again (Y/N)? " WITH NO ADVANCING
               ACCEPT WS-ANSWER
           END-PERFORM

      * Counting loop
           PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
               DISPLAY WS-I
           END-PERFORM

      * Nested counting loops in one statement
           PERFORM 5000-CELL
               VARYING WS-ROW FROM 1 BY 1 UNTIL WS-ROW > 3
                 AFTER WS-COL FROM 1 BY 1 UNTIL WS-COL > 4

15.3 EXIT PERFORM and EXIT PARAGRAPH

COBOL 2002 (supported by GnuCOBOL and IBM Enterprise COBOL):

EXIT PARAGRAPH and EXIT SECTION leave the current paragraph/section early — structured replacements for GO TO xxx-EXIT.

PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 100
               IF WS-TABLE-ITEM(WS-I) = SPACES
                   EXIT PERFORM                   *> break
               END-IF
               IF WS-TABLE-ITEM(WS-I)(1:1) = "*"
                   EXIT PERFORM CYCLE             *> continue
               END-IF
               PERFORM 6000-HANDLE-ITEM
           END-PERFORM

15.4 PERFORM pitfalls

Never fall into a performed paragraph: put STOP RUN/GOBACK at the end of the main paragraph so control doesn't drop into the next paragraph.

Overlapping ranges (PERFORM A THRU C while C is also performed alone with different exits) create hard-to-follow control flow.

A loop counter PIC 9 can never exceed 9: PERFORM VARYING I FROM 1 BY 1 UNTIL I > 9 with I PIC 9 loops forever (10 wraps to 0). Size counters with room to spare.