Skip to content
Units and Module Organization
step 1/5

Reading — step 1 of 5

Learn

~3 min readInterfaces, Operators, Idiomatic FPC

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:

  1. interface — what the unit exposes (types, function signatures, constants)
  2. implementation — the actual code
  3. end. — 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 program or top of interface: 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, format
  • StrUtils — additional string functions
  • Classes — TList, TStringList, TStream, TComponent
  • Math — math functions, rounding modes
  • DateUtils — date math (not just Now/Date)
  • Generics.Collections — TList<T>, TDictionary<K,V>
  • Variants — variant types
  • RegExpr — regex (not core, but bundled with FPC)
  • fpjson — JSON parsing
  • sqldb — database access
  • Sockets — 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 interface lean — expose only what callers need
  • Document interface section with /// comments for IDE tooltips
  • Avoid circular uses — split common types into a BaseTypes unit

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…