Nested & Recursive Programs

A program can contain other programs; each ends with END PROGRAM name.

26.1 Nested programs

A program can contain other programs; each ends with END PROGRAM name.

GLOBAL data (and files) declared in the outer program are visible to contained programs.

A nested program can be called only by its directly containing program — unless it is COMMON, in which case its siblings may call it too (INNER-A calls INNER-B above).

Nested programs give you private, reusable routines without separate compile units.

IDENTIFICATION DIVISION.
       PROGRAM-ID. OUTER.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-SHARED            PIC X(20) GLOBAL VALUE "visible inside".
       PROCEDURE DIVISION.
           CALL "INNER-A"
           CALL "INNER-B"
           STOP RUN.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. INNER-A.
       PROCEDURE DIVISION.
           DISPLAY "INNER-A sees: " WS-SHARED
           CALL "INNER-B"
           GOBACK.
       END PROGRAM INNER-A.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. INNER-B IS COMMON.
       PROCEDURE DIVISION.
           DISPLAY "INNER-B called"
           GOBACK.
       END PROGRAM INNER-B.

       END PROGRAM OUTER.

26.2 Recursion and LOCAL-STORAGE

COBOL-85 programs could not be called recursively. COBOL 2002 added the RECURSIVE attribute; LOCAL-STORAGE gives each invocation its own copy of variables.

Both programs live in one source file (cobc -x factdemo.cob); the last line printed is 15! = 1307674368000. On z/OS, recursive programs and LOCAL-STORAGE are supported by Enterprise COBOL; programs running in multithreaded environments also need the THREAD compiler option.

IDENTIFICATION DIVISION.
       PROGRAM-ID. FACTDEMO.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-N                 PIC S9(4)  COMP-5.
       01  WS-RESULT            PIC S9(18) COMP-5.
       01  ED-N                 PIC Z9.
       01  ED-RESULT            PIC Z(17)9.
       PROCEDURE DIVISION.
           PERFORM VARYING WS-N FROM 0 BY 1 UNTIL WS-N > 15
               CALL "FACT" USING BY CONTENT WS-N
                                 BY REFERENCE WS-RESULT
               MOVE WS-N TO ED-N
               MOVE WS-RESULT TO ED-RESULT
               DISPLAY ED-N "! = " FUNCTION TRIM(ED-RESULT)
           END-PERFORM
           STOP RUN.
       END PROGRAM FACTDEMO.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. FACT RECURSIVE.
       DATA DIVISION.
       LOCAL-STORAGE SECTION.
       01  LS-N-MINUS-1         PIC S9(4)  COMP-5.
       01  LS-SUB-RESULT        PIC S9(18) COMP-5.
       LINKAGE SECTION.
       01  LK-N                 PIC S9(4)  COMP-5.
       01  LK-RESULT            PIC S9(18) COMP-5.
       PROCEDURE DIVISION USING LK-N LK-RESULT.
           IF LK-N <= 1
               MOVE 1 TO LK-RESULT
           ELSE
               COMPUTE LS-N-MINUS-
…