Chapter 9
Chapter 9: Concepts of Programming Languages - Subprograms
Fundamentals of Subprograms
Each subprogram has a single entry point.
During the execution of the called subprogram, the calling program is suspended.
At any given time, only one subprogram is in execution.
Control always returns to the caller once the execution of the called subprogram terminates.
Parameters
Subprograms typically describe computations.
There are two ways for a non-method subprogram to access the data it processes:
Direct access to nonlocal variables:
Nonlocal variables are defined elsewhere but are visible within the subprogram.
To require computation on different data, new values must be assigned to these nonlocal variables between calls to the subprogram.
Extensive access to nonlocal variables can lead to reduced reliability of the program.
Parameter passing:
Data passed through parameters are accessed using names that are local to the subprogram.
Parameter passing is more flexible compared to direct access to nonlocal variables.
Types of Parameters
A formal parameter is a dummy variable included in the subprogram header which is utilized within the subprogram.
Formal parameters are bound to storage only when the subprogram is called.
An actual parameter represents a value or address used in the subprogram call statement.
Procedures and Functions
There are two distinct categories of subprograms:
Procedures:
A collection of statements that define parameterized computations.
Procedures do not return values.
Functions:
Structurally resemble procedures but are semantically modeled on mathematical functions.
Functions return values and are expected to produce no side effects.
They should not modify their parameters or any variables outside them.
In practice, functions may have side effects.
If procedures are not supported, functions can still be used without returning values.
Parameter-Passing Methods
Parameter-passing methods denote how parameters are transmitted to and/or from called subprograms.
Conceptual models include:
Physically move a value.
Move an access path (a pointer or reference) to a value.
Types of Parameter Passing
Pass-by-Value
The value of the actual parameter initializes the corresponding formal parameter.
Typically implemented by copying.
Advantages: Fast for scalar types.
Disadvantages:
Additional storage is required (actual parameter is stored twice).
Copying can be costly for large parameters.
Pass-by-Value-Result
The value of the actual parameter initializes the corresponding formal parameter which acts as a local variable.
At the termination of the subprogram, the value of the formal parameter is sent back to the actual parameter of the caller.
Sometimes referred to as pass-by-copy due to the copying process.
Requires an additional storage location and a copying operation.
Disadvantages: Those inherent to pass-by-value.
Pass-by-Reference
An access path (pointer or reference) is passed.
Also known as pass-by-sharing.
Advantage: Efficient passing process (no copying, no duplicated storage).
Disadvantages:
Slower accesses to formal parameters compared with pass-by-value.
Potential for unwanted side effects (collisions).
Possibility of unwanted aliases (broadened access path).
Pass-by-Name
The actual parameter is textually substituted for the corresponding formal parameter in all occurrences within the subprogram.
A formal parameter is bound to an access method (value or address) during the subprogram call.
The actual binding to a value or address is delayed until the formal parameter is assigned or referenced.
Issues:
Complex to implement and inefficient, adding complexity to the program and lowering its readability and reliability.
Not part of widely-used programming languages but used in assembly macros and generic parameters in languages like C++ and Java 5.0.
Potential Problems in Pass-by-Value-Result
Actual Parameter Collision:
Example Function:
sub(a, b) { a++; b--; }Situation:
Consider the call
sub(x, x):The order of copying the actual parameters affects the value of
x.
Address Computation Problems:
Example with Variables:
fun(int x, int index) { x = 17; index = 42; }On passing:
If
subis21, andfun(list[sub], sub)is called:If list[sub] is computed at the time of call,
17will be stored inlist[21].If computed prior to return,
17will be stored inlist[42].
Potential Problems in Pass-by-Reference
Unwanted Aliases:
1. Collisions can occur between actual parameters, illustrated in this function:
void fun(int &first, int &second) {}Call:
fun(total, total)firstandsecondinfunare now aliases.
2. Collisions between array elements:
If calling:
fun(list[i], list[j])and both parameters are passed by reference withi = j, thenfirstandsecondbecome aliases.3. Collisions between formal parameters and nonlocal variables:
Example:
int * global;In the main part:
void main() { … sub(global); }
In the sub function:
void sub(int * param) { … }Here,
paramandglobalact as aliases.
Parameter Passing Methods in Major Languages
C:
Default mode is pass-by-value; pass-by-reference is achieved using pointers.
C++:
Includes a special pointer type called the reference type for pass-by-reference.
Java:
All parameters are passed by value; however, object parameters are treated as passed by reference.
C#:
Default is pass-by-value; pass-by-reference is indicated by using
refwith both formal and actual parameters.
PHP:
Similar to C#, where either the actual or formal parameter can specify reference.
Perl:
All actual parameters are placed in a predefined array called
@_.
Python and Ruby:
Utilize pass-by-assignment, with data values being objects; the actual value is assigned to the formal parameter.
Summary
The definition of a subprogram depicts the actions they represent.
Subprograms can be categorized into functions and procedures.
There are four methods of parameter passing:
Pass-by-value
Pass-by-value-result
Pass-by-reference
Pass-by-name