Mainframe Path Start learning free
Core9 min readLesson 1 of 3

Where PL/I is used and how a program is built

PL/I was designed by IBM in the 1960s to serve both business and scientific programmers. A program is a set of procedures and blocks made of semicolon-terminated statements, with every variable described in a DECLARE.

Why PL/I exists

In the early 1960s, business shops used COBOL and scientific shops used FORTRAN. IBM designed PL/I alongside System/360 to do both: decimal arithmetic for money, floating point for engineering, plus pointers, strings and structured error handling. It never displaced COBOL, but many large organisations adopted it and never left.

Where you will find it

The current IBM compiler is Enterprise PL/I for z/OS. PL/I runs in batch, under CICS and IMS, and with embedded SQL for DB2, much as COBOL does.

The shape of a program

PL/I is free-form: statements end with a semicolon, not a period, and layout is up to you. Comments sit between /* and */. Keywords can be abbreviated, so DECLARE is often written DCL and PROCEDURE as PROC.

A small PL/I program (illustrative)
 HELLO: PROCEDURE OPTIONS(MAIN);
   DCL NAME   CHAR(20) INIT('WORLD');
   DCL COUNT  FIXED BIN(31) INIT(0);

   COUNT = COUNT + 1;
   PUT SKIP LIST('HELLO', NAME, COUNT);

   CALL SHOW_TOTAL(COUNT);

   SHOW_TOTAL: PROC(N);
     DCL N FIXED BIN(31);
     PUT SKIP LIST('TOTAL IS', N);
   END SHOW_TOTAL;
 END HELLO;
Reading the programWhat it means
HELLO: PROCEDURE OPTIONS(MAIN);
A labelled procedure. OPTIONS(MAIN) marks the entry point of the program.
DCL NAME CHAR(20) INIT('WORLD');
Declares a 20-character string with an initial value.
PUT SKIP LIST(...)
Stream output: start a new line and write the values, by default to SYSPRINT.
SHOW_TOTAL: PROC(N);
An internal procedure with one parameter, called with CALL.
END HELLO;
Ends the block named HELLO. Naming the label on END makes nesting easier to check.

Blocks and scope

PL/I has two kinds of block. A PROCEDURE is entered only when called. A BEGIN block is entered when execution reaches it, and is used to create local variables or to group statements in an ON-unit. Variables declared in a block are visible in that block and in blocks nested inside it, unless redeclared.

Block nesting and visibility
HELLO (main procedure)NAME and COUNT visible everywhere below
SHOW_TOTAL (internal procedure)N is local; can also see NAME and COUNT
BEGIN blocklocal work variables, freed when the block ends

Declare everything

PL/I will invent a declaration for an undeclared name, using defaults based on its first letter. A typing mistake therefore becomes a new variable instead of a compile error. The compiler warns about implicit declarations; treat those warnings as errors, and follow your site standard if it enforces explicit declarations through compiler options.

TRY IT YOURSELF

What PL/I keyword marks the procedure where a program starts? Type the option name inside the parentheses.

Show a hint

PROCEDURE OPTIONS(....)

Show the solution

MAIN. The main procedure is written NAME: PROCEDURE OPTIONS(MAIN);

Common mistakes

Ending statements with a period

PL/I statements end with a semicolon. A COBOL habit of periods produces confusing compile errors.

Relying on implicit declarations

A misspelt name silently becomes a new variable with default attributes. Declare every variable and act on the compiler's warnings.

Mismatched END statements

An END without a label closes the nearest open block, which may not be the one you meant. Put the label on END for procedures and long blocks.

What you will see at work

Key terms

Check your understanding.
Take this lesson's quiz and save your progress. Free.

Take the lesson quiz
PL/I data types, structures and built-in functions →