type TIntOp = function(A, B: Integer): Integer; declares a procedural type. Any plain function with that exact signature can be assigned to a variable of the type.
Pascal Medium · Lesson 1 · On the house
Procedural types and method pointers
Store routines in variables: function types, method pointers (of object), and callbacks. Lesson 1 is free — on the house.
Lessons · Pascal Medium · Lesson 1 of 10 · On the house
Procedural types and method pointers
Store routines in variables: function types, method pointers (of object), and callbacks.

In {$mode objfpc} you take a routine's address with @: Op := @Add;. Then Op(2, 3) calls it. In {$mode delphi} the @ is optional.
A method pointer adds of object: TNotify = procedure(Sender: TObject) of object;. It stores both the code address and the instance (Self), so it can only hold methods, not plain routines.
Event properties in the LCL (OnClick) are method pointers. That's why you assign Button.OnClick := @Form.Clicked; and not a plain procedure.
Check a procedural variable with Assigned(Op) before calling it. An unassigned one is nil, and calling it crashes.
Passing a procedural type as a parameter is how you write generic algorithms in classic Pascal: a sort that takes a compare function, a map that takes a transform.
callbacks
program ProcTypes;
{$mode objfpc}{$H+}
type
TIntOp = function(A, B: Integer): Integer;
TCounter = class
Total: Integer;
procedure Add(N: Integer);
end;
TIntProc = procedure(N: Integer) of object;
function Add(A, B: Integer): Integer; begin Result := A + B; end;
function Mul(A, B: Integer): Integer; begin Result := A * B; end;
procedure TCounter.Add(N: Integer); begin Total := Total + N; end;
function Fold(const Xs: array of Integer; Op: TIntOp; Init: Integer): Integer;
var X: Integer;
begin
Result := Init;
for X in Xs do Result := Op(Result, X);
end;
var
Op: TIntOp;
C: TCounter;
P: TIntProc;
begin
Op := nil;
writeln(Assigned(Op));
Op := @Mul;
writeln(Op(6, 7));
writeln(Fold([1, 2, 3, 4], @Add, 0), ' ', Fold([1, 2, 3, 4], @Mul, 1));
C := TCounter.Create;
P := @C.Add;
P(5); P(10);
writeln(C.Total);
C.Free;
end.
Quiz
What extra words make a procedural type hold methods?
Quiz
In objfpc mode, how do you assign function Add to a procedural variable Op?
Quiz
What does Fold([1, 2, 3, 4], @Mul, 1) return?
Quiz
What two things does a method pointer store?
Check
Match the still for: Procedural types and method pointers.
Open-book: the answers are on this page. Pass every quiz and check (5) to mark the lesson done. This visit: 0/5.