Computing: Free Pascal Programming

Using a function as a parameter in another function.

One of the amazing features of the Pascal programming language is the possibility to create custom types, and these types being allowed to be a little bit whatever the programmer wants. In this short tutorial, I show how we can define a custom type, that is not a new data type (based on some existing data type), but a "function type", i.e. a type that may be used to declare functions as variables of this type. This is a really easy way to pass a function as parameter to another function, or a procedure.

As example, lets take a function (I called it "Trigo"), that calculates the sine, cosine, tangent, or cotangent of an angle. The function should have two arguments: the trigonometric function, and the angle in degrees.

First, lets declare a new "function type":
    type
        TTrigoFunction = function(const Angle: Real): Real;

Then, lets declare our 4 trigonometric functions.
    function Sine(const X: Real): Real;
    begin
        Result := Sin(X);
    end;
    function Cosine(X: Real): Real;
    begin
        Result := Cos(X);
    end;
    function Tangent(X: Real): Real;
    begin
        Result := Sin(X) / Cos(X);
    end;
    function Cotangent(X: Real): Real;
    begin
        Result := Cos(X) / Sin(X);
    end;

Now, our "Trigo" function (the function DegToRad having been declared before...):
    function Trigo(TrigoFunction: TTrigoFunction; Angle: Real): Real;
    begin
        Result := TrigoFunction(DegToRad(Angle));
    end;

Finally the main program, that asks the user for a function and an angle, and displays the function value. Note that the functions Power() and RFormat() are used to get a formatted output of real numbers.
    program functions;
    uses
        SysUtils;
    type
        TTrigoFunction = function(const Angle: Real): Real;
    var
        rAngle: Real;
        sFunction: string;
        bContinue: Boolean;
    // Declarations of the functions Power() and RFormat() to be inserted here ...
    function DegToRad(Angle: Real): Real;
    begin
        Result := 2 * Pi * Angle / 360;
    end;
    // Declarations of the 4 trigonometric functions Sine, Cosine, Tangent, and Cotangent (cf. above) to insert here...
    function Trigo(TrigoFunction: TTrigoFunction; Angle: Real): Real;
    begin
        Result := TrigoFunction(DegToRad(Angle));
    end;
    {* Main program *}
    begin
        Writeln('Trigonometric functions:');
        repeat
            bContinue := True;
            Write('Function (sin, cos, tan, cotan)? '); Readln(sFunction);
            if (sFunction = 'sin') or (sFunction = 'cos') or (sFunction = 'tan') or (sFunction = 'cotan') then begin
                Write('Angle (in degrees) ? '); Readln(rAngle);
                if sFunction = 'sin' then
                    Writeln('sin(', RFormat(rAngle, 3), ') = ', RFormat(Trigo(@Sine, rAngle), 3))
                else if sFunction = 'cos' then
                    Writeln('cos(', RFormat(rAngle, 3), ') = ', RFormat(Trigo(@Cosine, rAngle), 3))
                else if sFunction = 'tan' then
                    Writeln('tan(', RFormat(rAngle, 3), ') = ', RFormat(Trigo(@Tangent, rAngle), 3))
                else
                    Writeln('cotan(', RFormat(rAngle, 3), ') = ', RFormat(Trigo(@Cotangent, rAngle), 3));
            end
            else
                bContinue := False;
            Writeln;
        until not bContinue;
    end.

I think that it's quite obvious that functions have to be passed to a function using pointers. Thus, we'll have to prefix the function name with the address operator @.

The screenshot shows a sample execution of the program.

Using a function as a parameter in another function program sample

If you find this text helpful, please, support me and this website by signing my guestbook.