When you write a program that is longer than the examples of the preceding chapters, it is almost always necessary to use functions and procedures. Using these subprogram modules enables you to write programs that are easy to understand and maintain.
There are two distinct types of subprogram modules in T. A procedure is a statement by itself. A function returns a value for use in expression evaluation.
A call to a subprogram has the form:
name[(argument{, argument})]Program execution jumps to the subprogram declaration. The call passes each argument to the subprogram. Upon completion of the statement list in a subprogram's body, program execution returns to the point immediately after the call.
The arguments used in a subprogram call must be compatible with the parameters defined in a subprogram declaration. Arguments are passed to a subprogram either by value or by reference. Arguments passed by value cannot be changed by the subprogram. This means that a variable used as an argument will have the same value before and after the subprogram call it was used in. When an argument is passed by reference, the address of the argument is given to the subprogram. In this case, a variable used as an argument may have a different value before and after the subprogram call.
In T, all standard data types can be passed by value. However, data structures, arrays, records, and unions, cannot be passed by value to a subprogram. For example, if you need to perform an operation on an array, you can pass the address of the entire array to a subprogram by reference.
A parameter is a list of variable declarations used in the subprogram. It has this form:
[var] name{, name} : type specificationThe key word var is used in a subprogram header to declare that each name in a parameter list is passed by reference. Its omission means that each name in a parameter list is passed by value.
Procedures may optionally contain a return statement of the form:
returnFunctions, however, must contain at least one return statement having the form:
return expressionThe expression's type must be compatible with the function's return type. The action of a return statement is always immediate. A subprogram may contain more than one return statement.
The declaration of a procedure takes the following form:
procedure name[(parameter{, parameter})]
declarations and statements
end name
Declarations within the procedure body are only visible within the procedure.
A procedure is a program statement. Program execution will resume at the next statement after a procedure call. Program execution returns from a procedure upon reaching the end of the procedure's statement list or by the action of a return statement anywhere in the body of the procedure.
An example of a procedure declaration:
procedure put_square(value : real)
put value*value
end put_square
The declaration of a function is similar to that of a procedure:
function name[(parameter{, parameter})] : type specification
declarations and statements
end name
The differences are that a return type must be specified after the list of
parameters as shown above and that a function must return a value using a return
statement.
Declarations within the function body are only visible within the function.
Functions are used in expressions. Program execution returns to the point in the expression after a function call. Program execution returns from a function upon reaching a return statement anywhere in the body of the function.
An example of a function declaration:
function square(value : real) : real
return value^2
end square
An example you should try now:
%
% "newton.t" uses Newton iteration to solve a
% simultaneous set of nonlinear equations:
%
% f1(x,y) = x^3 - x^2 * y + y^2 - 3.526
% f2(x,y) = x^3 + y^3 - 14.911
%
type matrix2 : array( 2, 2 ) of real
var q : matrix2
var x : real := 1.0
var y : real := 2.0
var f1, f2 : real
program
var i : int
for i := 1 ... 5 do
q(0, 0) := 3 * x^2 - 2 * x * y
q(0, 1) := 2 * y - x^2
q(1, 0) := 3 * x^2
q(1, 1) := 3 * y^2
if invert2(q) then
f1 := x^3 - x^2 * y + y^2 - 3.526
f2 := x^3 + y^3 - 14.911
x := x - q(0, 0) * f1 - q(0, 1) * f2
y := y - q(1, 0) * f1 - q(1, 1) * f2
put "x = ", x, " y = ", y
else
put "singular"
exit
end if
end for
end program
%
% invert a 2 x 2 square matrix of real numbers
%
function invert2(var m : matrix2) : boolean
var n : matrix2
var s : boolean
var det : real
det := m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)
if det = 0.0 then
s := false
else
s := true
n(0, 0) := m(1, 1) / det
n(0, 1) := -m(0, 1) / det
n(1, 0) := -m(1, 0) / det
n(1, 1) := m(0, 0) / det
m(0, 0) := n(0, 0)
m(0, 1) := n(0, 1)
m(1, 0) := n(1, 0)
m(1, 1) := n(1, 1)
end if
return s
end invert2
This chapter showed you how to declare functions and procedures in T programs. The main difference between these two types of subprograms is that a function is used in an expression and returns a value while a procedure is a statement by itself and does not return a value.