Procedures & Functions
A procedure performs an action and returns no value:
11.1 Procedures
A procedure performs an action and returns no value:
procedure PrintLine(Width: Integer);
var
I: Integer;
begin
for I := 1 to Width do
Write('-');
Writeln;
end;
begin
PrintLine(20);
end.11.2 Functions and Result
A function returns a value. Assign it either to the implicit variable Result (FPC objfpc/delphi modes, Delphi) or to the function name (classic Pascal):
Result behaves like a local variable: you can read it, modify it repeatedly, and pass it to other routines. For non-managed types it is not initialized — always assign it on every path. For managed types (strings, dynamic arrays, interfaces), do not assume it starts empty either: initialize it explicitly.
function Square(X: Double): Double;
begin
Result := X * X; // modern style
end;
function Cube(X: Double): Double;
begin
Cube := X * X * X; // classic style; still valid
end;11.3 Calling routines
PrintLine(10);
Y := Square(3.0) + Cube(2.0);
Square(5.0); // allowed: result discarded ({$X+} extended syntax, the default)
Randomize; // parentheses are optional for parameterless calls11.4 Exit with a value
function Sign(X: Integer): Integer;
begin
if X > 0 then Exit(1);
if X < 0 then Exit(-1);
Result := 0;
end;11.5 Overloading
Several routines can share a name if their parameter lists differ. Delphi requires the overload directive; FPC requires it only in delphi mode, but writing it is good practice everywhere:
The return type alone cannot distinguish overloads. Ambiguous calls (e.g. passing a Byte where both Integer and Int64 overloads fit) are resolved by the "closest match" rules or rejected.
function Max(A, B: Integer): Integer; overload;
begin
if A > B then Result := A else Result := B;
end;
function Max(A, B: Double): Double; overload;
begin
if A > B then Result := A else Result := B;
end;
function Max(const A, B: string): string; overload;
begin
if A > B then Result := A else Result := B;
end;11.6 Default parameters
Default parameters must come last and must be constant expressions. You cannot skip a middle parameter.
procedure Greet(const Name: string; const Greeting: string = 'Hello';
Excited: Boolean = False);
begin
Write(Greeting, ', ', Name);
if Excited then Writeln('!') else Writeln('.');
end;
begin
Greet('Ann'); // Hello, Ann.
Greet('Bob', 'Hi'); // Hi, Bob.
Greet('Cy', 'Hey', True); // Hey, Cy!
end.11.7 Inline routines
inline is a hint; the compiler may decline (recursive routines, routines with asm, routines whose body is not visible). FPC needs {$inline on} in some modes (on by default in objfpc/delphi since 3.x).
function Clamp(X, Lo, Hi: Integer): Integer; inline;
begin
if X < Lo then Result := Lo
else if X > Hi then Result := Hi
else Result := X;
end;11.8 Calling conventions
default in Delphi/FPC on x86: parameters in registers left-to-right on the stack (legacy)
C convention: right-to-left, caller cleans the stack Windows API convention COM: converts exceptions to HRESULT
stdcall on Windows, cdecl elsewhere (Delphi/FPC) On x86-64 and ARM there is one platform ABI; these directives matter mostly on 32-bit x86 and for documentation.