Суть этой возможности в Компонентном Паскале состоит в том, что можно создать переменную, которой позже можно присвоить адрес какой-либо процедуры, после чего, можно использовать эту переменную как саму процедуру.
При этом, нужно помнить, что список аргументов у переменной процедурного типа и самой процедуры должны совпадать.
MODULE FunctionalCalculator;
IMPORT Out := StdLog;
TYPE
CalculatorLong = PROCEDURE (VAR acc: LONGINT; cur: INTEGER);
CalculatorBool = PROCEDURE (VAR acc: BOOLEAN; a, b: INTEGER);
PROCEDURE Add(VAR acc: LONGINT; cur: INTEGER);
BEGIN acc := acc + cur END Add;
PROCEDURE Sub(VAR acc: LONGINT; cur: INTEGER);
BEGIN acc := acc - cur END Sub;
PROCEDURE Mul(VAR acc: LONGINT; cur: INTEGER);
BEGIN acc := acc * cur END Mul;
PROCEDURE Div(VAR acc: LONGINT; cur: INTEGER);
BEGIN acc := acc DIV cur END Div;
PROCEDURE Greater(VAR acc: BOOLEAN; a, b: INTEGER);
BEGIN acc := acc & (a > b) END Greater;
PROCEDURE Less(VAR acc: BOOLEAN; a, b: INTEGER);
BEGIN acc := acc & (a < b) END Less;
PROCEDURE ReduceLong(IN nums: ARRAY OF INTEGER; c: CalculatorLong): LONGINT;
VAR
i: INTEGER;
acc: LONGINT;
BEGIN
acc := nums[0];
FOR i := 1 TO LEN(nums) - 1 DO c(acc, nums[i]) END;
RETURN acc;
END ReduceLong;
PROCEDURE ReduceBool(IN nums: ARRAY OF INTEGER; c: CalculatorBool): BOOLEAN;
VAR
i: INTEGER;
acc: BOOLEAN;
BEGIN
acc := TRUE; i := 1;
REPEAT
c(acc, nums[i-1], nums[i]);
INC(i);
UNTIL (i = LEN(nums)) OR ~acc;
RETURN acc;
END ReduceBool;
PROCEDURE Start*;
VAR
sn: ARRAY 5 OF INTEGER; (* sn - some nums *)
orderedNums: ARRAY 3 OF INTEGER;
sum, mul: LONGINT;
greater, less: BOOLEAN;
BEGIN
sn[0] := 1; sn[1] := 3; sn[2] := 5; sn[3] := 7; sn[4] := 9;
sum := ReduceLong(sn, Add);
Out.String('sum = '); Out.Int(sum); Out.Ln;
mul := ReduceLong(sn, Mul);
Out.String('mul = '); Out.Int(mul); Out.Ln;
orderedNums[0] := 7;
orderedNums[1] := 5;
orderedNums[2] := 1;
greater := ReduceBool(orderedNums, Greater);
Out.String('greater = '); Out.Bool(greater); Out.Ln;
less := ReduceBool(orderedNums, Less);
Out.String('less = '); Out.Bool(less); Out.Ln;
END Start;
END FunctionalCalculator.
Если переменной процедурного типа не присвоить значение, она будет иметь значение NIL.