New Easytrieve programmers search the PROC statement for a USING clause and find none. Broadcom PROC modules do not declare formal parameters. Instead, caller and callee agree on field names— move gross pay into WORK-GROSS, PERFORM CALC-TAX, read TAX-AMT when END-PROC returns. That implicit contract is the Easytrieve parameter model. This tutorial documents input-output field conventions, scratch versus shared fields, contrast with MACRO compile-time parameters and CALL USING to external programs, PARM job-level values, and maintainability patterns that keep modular code readable without linkage sections. Understanding parameters prevents hidden coupling where PROCs overwrite globals callers still needed.
PROC opens a module; PERFORM invokes it. Neither statement carries a parenthetical field list in standard Easytrieve grammar. All Library DEFINE fields, FILE record fields, and working storage are visible inside every PROC in the same program. Parameters are therefore a design convention: document which fields the caller must populate before PERFORM and which fields the PROC updates before END-PROC. Teams sometimes prefix names IN- and OUT- or use a comment block above each PROC listing its contract.
12345678910111213141516171819202122* Caller contract: * IN: WORK-GROSS, WORK-STATE * OUT: WORK-TAX-AMT, WORK-ERROR-FLAG MOVE GROSS-PAY TO WORK-GROSS MOVE STATE-CODE TO WORK-STATE PERFORM CALC-STATE-TAX IF WORK-ERROR-FLAG EQ 'N' NET-PAY = GROSS-PAY - WORK-TAX-AMT END-IF CALC-STATE-TAX. PROC IF WORK-STATE EQ 'NY' WORK-TAX-AMT = WORK-GROSS * 0.08 WORK-ERROR-FLAG = 'N' ELSE IF WORK-STATE EQ SPACES WORK-ERROR-FLAG = 'Y' ELSE WORK-TAX-AMT = WORK-GROSS * 0.05 WORK-ERROR-FLAG = 'N' END-IF END-PROC
| Strategy | Description | Tradeoff |
|---|---|---|
| Dedicated WORK fields | IN-/OUT- prefixes for PROC interface | Verbose but clear at PERFORM sites |
| Record fields in place | PROC reads EMP-GROSS directly from FILE buffer | Less MOVE overhead; tight coupling to layout |
| Parameter block record | Group field PARMS with subfields | One MOVE passes many values conceptually |
| Status flag return | ERROR-FLAG or RC field as output parameter | Caller must check flag every time |
| Scratch inside PROC | Use local WORK names; only expose results | Protects caller from intermediate junk values |
Because PROC does not isolate storage, every MOVE inside a module may change fields the caller did not list as outputs— accidental side effects. A CALC module that reuses WORK-GROSS for intermediate math clobbering the caller's gross value causes subtle bugs on the next IF. Prefer scratch names inside PROC for intermediates or save and restore critical caller fields at module start and end when wrapping legacy logic you cannot refactor immediately.
MACRO prototypes declare positional and keyword parameters with ampersand substitution in the macro body. Invocation %MYMAC A B KEY=VAL expands at compile time—parameters become literal text in generated statements. Use macros when parameterization is about generating different field names, FILE layouts, or repeated DEFINE blocks. Use PROC when runtime logic executes with real data values in shared fields. A macro cannot replace PERFORM for iterative record processing; a PROC cannot generate ten field definitions from one template without repetitive source.
1234567891011* MACRO compile-time parameter example (conceptual): * MACRO 2 &FNAME &FLEN * &FNAME &FLEN 1 * MEND * %MYMAC EMP-NO 6 expands into field definition text * PROC runtime — no & substitution: PERFORM FORMAT-NAME FORMAT-NAME. PROC OUT-NAME = IN-FIRST || ' ' || IN-LAST END-PROC
CALL invokes external subprograms with explicit USING lists and optional RETURNS for numeric return codes. Linkage conventions pass addresses per COBOL, Assembler, or C rules documented in the CALL chapter. Use CALL when parameterized logic lives outside Easytrieve or must be binary-shared across languages. Thin PROC wrappers prepare USING fields from Easytrieve working storage, CALL the external module, map RETURNS into ERROR-FLAG, and END-PROC—giving callers a PERFORM interface around external parameters.
PARM supplies run-time job parameters—report dates, company id, test versus production flags— often parsed into fields at program start in START. PROC or implied JOB beginning. Those fields behave like global configuration parameters every module may read. They differ from per-invocation PERFORM parameters that change each record. Copy PARM-derived values into WORK fields when a PROC needs a stable snapshot unaffected by later PARM field overwrites in the same run.
The same CALC-DISCOUNT. PROC serves multiple PERFORM sites by setting DISC-TYPE before each call. First branch MOVE 'EMP' TO DISC-TYPE then PERFORM; second branch MOVE 'SEN' TO DISC-TYPE. The PROC reads DISC-TYPE as an input parameter field selecting logic inside one module instead of duplicating three nearly identical PROCs. Discipline matters: always set every input including mode switches before PERFORM; document allowed DISC-TYPE values in module header comments.
PROC does not have a list of labeled slots on the door. You put the ingredients on the shared counter with sticky notes saying input and output, tell the cook to start the recipe—PERFORM—and when they say done—END-PROC—you read the output sticky note. MACRO is like a copy machine that prints different recipe templates before cooking starts. CALL is asking a chef in another kitchen to cook using a tray you hand through the window—USING lists what is on the tray.
1. Easytrieve PROC modules accept formal parameters on the PROC line like:
2. To pass data into CALC-TAX. PROC you typically:
3. MACRO parameters differ from PROC because:
4. CALL subprogram USING passes parameters via:
5. After END-PROC returns, output values are read from: