Declaring Generic Types and Routines
Free Pascal supports generics using the generic keyword on the declaration and specialize at the point of use, in addition to Delphi-compatible syntax with angle brackets when {$mode delphi} is active. A generic type such as generic TStack<T> = class declares a placeholder type parameter T that stands in for any concrete type; the compiler generates a distinct specialized version — specialize TStack<Integer> versus specialize TStack<string> — the first time each unique type argument is used, a process called monomorphization. This gives you compile-time type safety with no runtime casting or boxing, unlike a container built around TObject or Variant.
Cricket analogy: A generic TStack<T> is like a standardized nets-practice drill template that can be run with any equipment — 'specialize' it with a cricket ball for pace practice or a tennis ball for reflex drills, and the coach gets a purpose-built session without rewriting the drill structure each time.
Constraints and Generic Containers
Free Pascal lets you constrain a type parameter to a class hierarchy or interface, written as generic TRepository<T: TObject> = class, which restricts T to TObject descendants and allows the compiler to safely call TObject methods like Free on values of type T. The RTL's Generics.Collections unit ships ready-made specializations such as specialize TList<T>, specialize TDictionary<TKey, TValue>, and specialize TObjectList<T>, mirroring .NET-style generic collections; TObjectList<T> additionally owns its elements and frees them automatically when the list is cleared or destroyed, provided OwnsObjects is true. Generic routines (standalone functions, not just types) are also supported, letting you write a single generic function Max<T>(A, B: T): T that works across any ordinal or comparable type without duplicating code for each type.
Cricket analogy: A type constraint 'T: TObject' is like a franchise rule that any overseas player (T) must at minimum be board-certified (a TObject descendant) before selection, letting the team management safely apply standard contract clauses (Free) to any player who qualifies.
Limitations and Practical Use
Free Pascal's generics have real limitations compared to C++ templates: operator constraints are limited, generic type inference for routines is weaker (you often must specify the type explicitly, e.g. specialize Max<Integer>(3, 5)), and generics cannot be combined with certain older RTTI features without extra {$modeswitch} directives. In practice, the most common use is via Generics.Collections for TList<T> and TDictionary<TKey, TValue> rather than authoring your own generic classes, since hand-rolled generics can trigger obscure compiler errors around forward-declared specializations and circular unit dependencies that are easy to hit but hard to diagnose for newcomers.
Cricket analogy: Weaker type inference is like a franchise not automatically knowing whether a trialist bats left or right-handed — you must explicitly state 'left-handed opener' (specify the type) rather than the selectors inferring it from a single net session.
uses
Generics.Collections;
type
generic TStack<T> = class
private
FItems: array of T;
public
procedure Push(const AValue: T);
function Pop: T;
function IsEmpty: Boolean;
end;
procedure TStack.Push(const AValue: T);
begin
SetLength(FItems, Length(FItems) + 1);
FItems[High(FItems)] := AValue;
end;
function TStack.Pop: T;
begin
Result := FItems[High(FItems)];
SetLength(FItems, Length(FItems) - 1);
end;
function TStack.IsEmpty: Boolean;
begin
Result := Length(FItems) = 0;
end;
var
IntStack: specialize TStack<Integer>;
Names: specialize TList<string>;
begin
IntStack := specialize TStack<Integer>.Create;
IntStack.Push(42);
Names := specialize TList<string>.Create;
Names.Add('Wirth');
Names.Add('Kay');
end.In {$mode delphi} or {$mode objfpc} with the appropriate modeswitch, you can often omit the specialize keyword and write TStack<Integer> directly, matching Delphi syntax. Free Pascal's classic {$mode fpc} requires the explicit specialize keyword everywhere a specialization is used.
- Declare generics with
genericand instantiate them withspecialize, or use Delphi-style angle brackets under the right mode. - The compiler monomorphizes each unique type argument into its own concrete specialized type at compile time.
- Type constraints like
T: TObjectrestrict whatTcan be and unlock safe calls to base-class methods. Generics.Collectionsprovides ready-madeTList<T>,TDictionary<TKey, TValue>, andTObjectList<T>.TObjectList<T>withOwnsObjects := Trueautomatically frees its elements on clear/destroy.- Generic routines exist too, but type inference is weaker than in some languages, often requiring explicit type arguments.
- Prefer the RTL's built-in generic collections over hand-rolled generics to avoid obscure compiler errors.
Practice what you learned
1. Which keyword is used to instantiate a concrete version of a generic type in classic Free Pascal mode?
2. What does the constraint in `generic TRepository<T: TObject> = class` guarantee?
3. What does setting `OwnsObjects := True` on a `TObjectList<T>` do?
4. Compared to some other languages, how does Free Pascal's generic type inference for standalone routines typically behave?
5. What compiler process occurs when multiple different types are used with the same generic type declaration?
Was this page helpful?
You May Also Like
Object-Oriented Pascal
Learn how Pascal implements classes, inheritance, polymorphism, and constructors/destructors through the `class` type and virtual methods.
Debugging Pascal Programs
Learn practical techniques for diagnosing runtime errors, memory issues, and logic bugs in Free Pascal programs using the Lazarus debugger and compiler checks.
Pascal vs Modern Languages
Compare Pascal's design philosophy, syntax, and type system against modern languages like C++, Python, and Java to understand its strengths and trade-offs.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics