Key Takeaways — Chapter 7: Iteration Patterns
Core Concepts
-
PERFORM is COBOL's universal control-flow mechanism. Basic PERFORM structures programs top-down. PERFORM TIMES handles fixed repetition. PERFORM UNTIL handles conditional loops. PERFORM VARYING handles counting and table traversal. Master all forms.
-
TEST BEFORE (default) may execute zero times; TEST AFTER always executes at least once. This distinction determines whether you need a "priming read" pattern. Choose deliberately based on your requirements.
-
The priming read pattern is essential for sequential file processing. Read the first record before the loop, process it inside the loop, and read the next record at the end of each iteration. Getting this wrong causes off-by-one errors.
-
The VARYING counter exceeds the limit after the loop. After
PERFORM ... VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 10, WS-IDX is 11, not 10. Always account for this. -
Every production loop needs a safety net. Maximum iteration counters, progress verification, and checkpoint logging are mandatory defensive practices for batch programs.
Patterns to Remember
- Priming read: READ before loop, process + READ inside loop (TEST BEFORE)
- Safety counter:
UNTIL condition OR counter >= max-limit - Progress check: Track last-processed key; if unchanged for N iterations, terminate
- Checkpoint logging: Display progress every N records with record count and key
- Constant hoisting: Move invariant calculations outside the loop body
- Early exit from sorted search: Add
OR key > targetto UNTIL condition
PERFORM Form Selection Guide
| Situation | Best Form |
|---|---|
| Execute a paragraph once | Basic PERFORM |
| Fixed number of iterations, all must execute | PERFORM ... TIMES |
| Loop until a condition (file processing) | PERFORM ... UNTIL |
| Need at least one execution | PERFORM ... WITH TEST AFTER UNTIL |
| Counting or table traversal | PERFORM ... VARYING |
| Two-dimensional table traversal | PERFORM ... VARYING ... AFTER |
| Short, local loop body (1-5 lines) | Inline PERFORM ... END-PERFORM |
| Guard clause / early exit pattern | PERFORM ... THRU (with exit paragraph) |
| Break out of inline loop (COBOL 2002+) | EXIT PERFORM |
| Skip iteration in inline loop (COBOL 2002+) | EXIT PERFORM CYCLE |
Defensive Programming Checklist
- [ ] Every PERFORM UNTIL has a maximum iteration safety counter
- [ ] Loop progress is verified (index or key must advance)
- [ ] Long-running loops have checkpoint logging at regular intervals
- [ ] Post-loop code checks which exit condition was triggered
- [ ] VARYING counters are never modified inside the performed paragraph
- [ ] WS-REPRICE-ATTEMPT-style counters are initialized at the correct scope
- [ ] Invariant calculations are hoisted outside the loop body
Common Pitfalls
| Pitfall | Consequence | Prevention |
|---|---|---|
| Missing priming read | First record skipped or double-processed | Follow the standard pattern |
| UNTIL = instead of > | Off-by-one: last element skipped | Use > for upper-bound conditions |
| Modifying VARYING counter in loop body | Unpredictable behavior, possible infinite loop | Never modify the counter inside the loop |
| No safety counter | Infinite loop blocks batch window | Always include OR counter >= max |
| Stale loop control variables | Logic errors on subsequent iterations | Initialize at correct scope |
| PERFORM THRU with intervening paragraphs | Unintended code execution | Use strict naming conventions for THRU ranges |