Why shops split code into subprograms
So far every program you have written has been one self-contained unit:
read input, do the work, STOP RUN. Real mainframe systems do not look
like that. A bank's overnight batch is hundreds of programs, and most of
them CALL shared subprograms to do common jobs: validate an account
number, work out the number of days between two dates, calculate tax,
format an address, write an audit record.
Why split code up?
- Reuse. The rule for "is this a valid IBAN" should exist once. If forty programs each had their own copy, forty copies would need fixing the day the rule changes, and one would be missed.
- Separate compilation. Each subprogram is its own source member, compiled on its own. A change to the tax routine means recompiling and testing one small program, not every batch job that uses it.
- Load modules. On z/OS the compiled and link-edited program is a
load module stored in a load library (a PDS or PDSE). When a job step
runs
EXEC PGM=PAYRUN, the system loadsPAYRUN, andPAYRUNcan in turn loadTAXCALCfrom the library when it calls it. - Team ownership. One team owns the date routines, another owns customer validation. The interface between them is the parameter list.
The vocabulary
The program that runs first is the main program; the one it calls is
the called program or subprogram. Together they form a run unit.
The caller passes data with CALL ... USING; the called program describes
that data in its LINKAGE SECTION and names it on
PROCEDURE DIVISION USING. It finishes with GOBACK, which returns to the
statement after the CALL.
Here is the whole idea in one source file. TAXCALC is written inside
PAYRUN, between PAYRUN's procedure code and its END PROGRAM. That is
a nested program, which you will write yourself later in this module:
IDENTIFICATION DIVISION.
PROGRAM-ID. PAYRUN.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-GROSS PIC 9(5)V99 VALUE 3000.00.
01 WS-TAX PIC 9(5)V99.
01 WS-TAX-ED PIC Z(4)9.99.
PROCEDURE DIVISION.
DISPLAY "PAYRUN: CALLING TAXCALC"
CALL "TAXCALC" USING WS-GROSS WS-TAX
MOVE WS-TAX TO WS-TAX-ED
DISPLAY "PAYRUN: TAX IS " WS-TAX-ED
STOP RUN.
IDENTIFICATION DIVISION.
PROGRAM-ID. TAXCALC.
DATA DIVISION.
LINKAGE SECTION.
01 LS-GROSS PIC 9(5)V99.
01 LS-TAX PIC 9(5)V99.
PROCEDURE DIVISION USING LS-GROSS LS-TAX.
COMPUTE LS-TAX ROUNDED = LS-GROSS * 0.20
DISPLAY "TAXCALC: DONE"
GOBACK.
END PROGRAM TAXCALC.
END PROGRAM PAYRUN.
PAYRUN: CALLING TAXCALC
TAXCALC: DONE
PAYRUN: TAX IS 600.00
TAXCALC has no storage for LS-TAX. When it computes into LS-TAX it is
writing straight into PAYRUN's WS-TAX, because the CALL passed the
address of that field. That is why PAYRUN sees the result.
Copybooks: the other half of sharing
Programs that pass a customer record to each other must agree on its
layout to the byte. So nobody types the layout twice: it lives in a
copybook, a source member that the compiler pastes in wherever a
program says COPY CUSTREC. Change the copybook, recompile the programs
that use it, and they all agree again. You will use copybooks at the end
of this module.
On the job
When you join a mainframe team, one of the first things to learn is which common routines already exist: date conversion, check digits, error logging, abend handling. Writing your own when the shop has one is a classic newcomer mistake, and code review will catch it. Ask where the copybook and load libraries are, and how the shop's change tool (Endevor, ChangeMan) promotes a new version of a module.