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.

Illustration for Pascal
Lesson 1 is on the house.

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.

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.
Match this when you type.

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.