| home | contents | previous | next page | send comment | send link | add bookmark |

5. Subprograms

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.

subprogram calls

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.

subprogram parameters

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 specification
The 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.

return statement

Procedures may optionally contain a return statement of the form:

return
Functions, however, must contain at least one return statement having the form:
return expression
The 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.

procedure declarations

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

function declarations

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

summary

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.


| home | contents | previous | next page | send comment | send link | add bookmark |

Copyright © 2004, Stephen R. Schmitt