# Software Engineers Handbook/Language Dictionary/PLI/procedures

Note: This article requires basic knowledge of PL/I which can be found in Software Engineers Handbook/Language Dictionary/PLI.

### Procedures
#### Procedures as Subroutines

A PL/I program may contain user defined subroutines:
* The definition of a (internal) subroutine starts with
** The name of the subroutine followed by ':'
** The keyword PROCEDURE (abbreviation: PROC)
** Optionally a parameter-descriptor list in brackets
* The subroutine will be invoked by CALL statements
* The subroutine may be left by optionally return statements

#### Procedures as Functions

A PL/I programm may contain user defined functions:
* The definition of a (internal) function starts with
** The name of the function followed by ':'
** The keyword PROCEDURE (abbreviation: PROC)
** Optionally a parameter-descriptor list in brackets
** The keyword RETURNS followed by the type of the return value in brackets
* The result of the function may be used in expressions
* The subroutine must have at least one return statements which returns the result

### Changes of Parameter Variables

When a procedure is invoked with variables as parameter this parameters may be passed in one of the following ways:
* "By reference" (also known as "by name") which means changes inside the procedure alters the original variable.
* "By value" (or "as dummy") which means changes inside the procedure alters only a copy of the original variable.
In PL/I a variable which is
* of simple type, e.g. char, number, ...
* an array of simple type variables
* a structure of simple type variables $^{[1]}$
is passed by reference if and only if the variable matches exactly the argument definition inside the procedure.

#### Asterisk Notation

* If the size attribute of the parameter definition is an asterisk every matching variable with any size is passed by reference.
* If the dimension of the parameter definition is an asterisk every matching variable with any dimension is passed by reference.

### Locale Variables
#### Scope

The scope of PL/I variables is confined to procedures in which they are declared.

#### Storage Class

There are two storage class locale variables may have.$^{[2]}$
Automatic storage:
* Its value is lost between successive invocations of the procedure
* If the variable has the INIT attribute initialisation is done every time the procedure is invoiced
* The keyword AUTOMATIC may be abbreviated as AUTO
* Locale variables are automatic by default$^{[3]}$
Static storage:
* Its value is saved between successive invocations of the procedure
* If the variable has the INIT attribute initialisation is done only once when program starts

### Multiple Entries

Procedures may have more than one entry.

### Multiple Parm Lists

Using the attribute GENERIC procedures may have more than one parm list.
Parm descriptor may contain the attributes of the calling parameters:
Parm descriptor may contain the number of the calling parameters:
Parm descriptor may contain the number of dimensions of the calling parameters:

### Recursive Procedures

A procedure may be invoked recursively if the RECURSIVE option is specified.
* Every invocation of the procedure has it's own value of the calling parameters
* Every invocation of the procedure has it's own value of local variables which are automatic
* All invocations of the procedure have a common value of local variables which are static

### Entry Variables and Parameters

Like other data procedures may be used as variables and parameters.

### External Procedures

A procedure may be external, i.e. the source may be contained in a separate file. This approach offers the possibility to use this procedure in more than one main program. Every program or procedure which uses an external procedure must declare this procedure.

#### Static Linking

Making a program executable requires two steps:
* Compile the program and all the used external procedures in any order.
* Use the linkage editor to combine the compile objects to an executable program.
The executable program now contains the binary code of its procedures at linking time, i.e. if an external procedure is changed and recompiled after linking time this would not change the behaviour of the executable program.

#### Fetched Procedures

PL/I allows dynamic linking of external procedures, i.e. a main program may load the last compiled version of a procedure at run time.
The statement FETCH ABC loads the binary of procedure ABC from auxiliary storage into main storage (unless ABC already exists in main storage).
The statement RELEASE ABC frees main storage occupied by ABC$^{[4]}$.

#### "Pseudo-Fetching"

If in the example above both b1 and b2 are true ...
* abc will be released after the first call
* abc will be loaded again before the second call
... which is not very effective.
PL/I has the following properties:
* A procedure will be recognised as to_be_loaded_dynamicly iff the program somewhere contains a fetch or release statement, it is not necessary that this statement will be reached at any time.
* If a procedure recognised as to_be_loaded_dynamicly is invoked at runtime it will be fetched automatically if necessary.
Using this two properties the program above may be rewritten as:

### Notes

* $^{[1]}$ or an array of structures of simple type variables ...
* $^{[2]}$ there are two more storage class (based and controlled for dynamically allocated storage) which will be explained in another wikibooks PL/I special.
* $^{[3]}$ in PL/I default values may be altered using the DEFAULT statement.
* $^{[4]}$ the FREE statement for a fetched procedure will also free the local static variables of this procedure.