Procedures and Functions

7.1 Declarations

procedure Greet(const Name: string);
begin
  Writeln('Hello, ', Name);
end;

function Add(A, B: Integer): Integer;
begin
  Result := A + B;          // implicit Result variable (preferred)
end;

function Max(A, B: Integer): Integer;
begin
  if A > B then
    Exit(A);                // Exit with a value
  Result := B;
end;

7.2 Parameter Modes

Copy passed in Read-only. Efficient for strings, records, and interfaces (no copy/refcount). Use it for most input parameters.

By reference (the caller's variable is modified) By reference, output only (managed types are cleared on entry) Force by-reference const Untyped var/const

procedure Fill(var Buf; Count: Integer) (low-level)

procedure Swap(var A, B: Integer);
var
  T: Integer;
begin
  T := A; A := B; B := T;
end;

procedure GetMinMax(const Values: array of Integer; out MinV, MaxV: Integer);
begin
  MinV := MinIntValue(Values);
  MaxV := MaxIntValue(Values);
end;

7.3 Default Parameters, Overloading and Open Arrays

procedure Log(const Msg: string; Level: Integer = 1; const Prefix: string = '[LOG]');
begin
  Writeln(Prefix, ' ', Level, ': ', Msg);
end;

function Area(Radius: Double): Double; overload;
begin
  Result := Pi * Sqr(Radius);
end;

function Area(Width, Height: Double): Double; overload;
begin
  Result := Width * Height;
end;

function Sum(const Values: array of Integer): Integer;     // open array parameter
begin
  Result := 0;
  for var V in Values do Inc(Result, V);
end;

procedure PrintAll(const Args: array of const);             // variant open array
begin
  for var I := 0 to High(Args) do
    case Args[I].VType of
      vtInteger: Writeln('Int: ', Args[I].VInteger);
      vtUnicodeString: Writeln('Str: ', string(Args[I].VUnicodeString));
      vtExtended: Writeln('Real: ', Args[I].VExtended^:0:2);
    end;
end;

Writeln(Sum([1, 2, 3, 4]));
PrintAll([42, 'text', 3.14]);

7.4 Nested Routines, Forward Declarations and Recursion

function Factorial(N: Integer): Int64;
begin
  if N <= 1 then Result := 1
  else Result := N * Factorial(N - 1);
end;

procedure Outer;
var
  Counter: Integer;

  procedure Inner;          // nested: has access to Outer's locals
  begin
    Inc(Counter);
  end;

begin
  Counter := 0;
  Inner; Inner;
  Writeln(Counter);         // 2
end;

procedure B; forward;       // forward declaration (within the implementation)
procedure A; begin B; end;
procedure B; begin Writeln('B'); end;

7.5 Calling Conventions and Directives

register (default, fastest on Win32), stdcall (Windows API), cdecl (C libraries), pascal, safecall (COM).

inline (inlining hint), overload, deprecated 'message', platform, experimental, external 'lib.dll', varargs, assembler, noreturn.

7.6 Procedural Types

type
  TMathFunc = function(X: Double): Double;
  TNotify = procedure(Sender: TObject) of object;     // method pointer (Module 20)
  TCallback = reference to procedure(const S: string); // anonymous method reference (Module 24)

function Apply(F: TMathFunc; X: Double): Double;
begin
  Result := F(X);
end;

function Square(X: Double): Double;
begin
  Result := X * X;
end;

Writeln(Apply(Square, 5):0:1);