Reading — step 1 of 5
Learn
For anything beyond a single-file program, Pascal organizes code into units — .pas files with explicit interface and implementation sections.
Anatomy of a unit
File MathUtils.pas:
unit MathUtils;
{$mode objfpc}{$H+}
interface
type
TPoint = record X, Y: real; end;
function Distance(a, b: TPoint): real;
function IsPositive(n: integer): boolean;
implementation
uses Math;
function Distance(a, b: TPoint): real;
begin
Result := Sqrt(Sqr(a.X - b.X) + Sqr(a.Y - b.Y));
end;
function IsPositive(n: integer): boolean;
begin
Result := n > 0;
end;
end.
Three sections:
interface— what the unit exposes (types, function signatures, constants)implementation— the actual codeend.— closes the unit
Only the interface is visible to callers. The implementation is private to this unit.
Using a unit
program demo;
uses MathUtils; { resolves to MathUtils.pas in the include path }
var a, b: TPoint;
begin
a.X := 0; a.Y := 0;
b.X := 3; b.Y := 4;
WriteLn(Distance(a, b)); { 5 }
end.
uses clauses
- In
programor top ofinterface: imports the unit globally - In
implementation: imports for use only inside the implementation (avoids circular dependencies in the interface)
interface
uses TypeDefs; { needed in the interface (return types, etc.) }
implementation
uses HelperPkg; { only needed in implementation }
Mode directives
FreePascal has multiple modes — set with {$mode <name>}:
{$mode fpc}— default, supports old Turbo Pascal{$mode objfpc}— modern FPC, allows Object Pascal classes, generics, more{$mode delphi}— Delphi compatibility{$mode iso}— strict ISO Pascal
Most modern code uses {$mode objfpc}{$H+}. The {$H+} enables long strings (AnsiString over the legacy string[255]).
Initialization and finalization
Units can have initialization and finalization sections — code run on program start/end:
implementation
...
initialization
WriteLn('MathUtils loaded');
InitTables;
finalization
WriteLn('MathUtils unloading');
FreeTables;
end.
Run in declared order on startup, reverse order on shutdown.
Standard library units
Units worth knowing in FPC:
SysUtils— strings, exceptions, files, formatStrUtils— additional string functionsClasses— TList, TStringList, TStream, TComponentMath— math functions, rounding modesDateUtils— date math (not justNow/Date)Generics.Collections— TList<T>, TDictionary<K,V>Variants— variant typesRegExpr— regex (not core, but bundled with FPC)fpjson— JSON parsingsqldb— database accessSockets— networking primitives
Project organization
A typical FPC project:
src/
main.pas { the program file }
domain/
Account.pas
Transaction.pas
db/
Connection.pas
util/
Logger.pas
Lazarus's project file (.lpi) lists units. For command-line builds, fpc -Fu./src/domain main.pas adds search paths.
Best practices
- ONE class per unit (Delphi convention; FPC allows more but it scales worse)
- Unit name = file name (case-insensitive on most platforms but NOT all)
- Keep
interfacelean — expose only what callers need - Document interface section with
///comments for IDE tooltips - Avoid circular
uses— split common types into aBaseTypesunit
Units are how you scale Pascal beyond toy programs. Lazarus IDE itself is built from thousands of units, all using this same machinery.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…