Key Takeaways: Generics

  1. Generics eliminate code duplication while preserving type safety. Write a data structure or algorithm once with a type parameter T, then specialize it for any concrete type. One TStack<T> replaces TIntStack, TStringStack, and TExpenseStack.

  2. The compiler generates type-specific code for each specialization. There is no runtime overhead — generics are resolved at compile time. TFPGList<Integer> compiles to code just as fast as a hand-written integer list.

  3. **In {$mode objfpc}`, use `generic` to declare and `specialize` to instantiate.** These keywords make the generic nature of types explicit. In `{$mode delphi}, bare angle brackets serve the same purpose.

  4. Type constraints restrict what T can be. Use T: class for class types, T: constructor for types with parameterless constructors, T: record for value types, or T: IInterface for types implementing a specific interface. Constraints let the compiler verify that operations on T are valid.

  5. Use built-in collections from the fgl unit. TFPGList<T> for value types, TFPGObjectList<T> for objects (with optional ownership), TFPGMap<K,V> for key-value pairs. These are well-tested and should be your default choice.

  6. TFPGObjectList<T> with FreeObjects := True automates memory management. When items are removed or the list is destroyed, contained objects are freed automatically. This eliminates a major class of memory leaks.

  7. Generic algorithms work with any type. A generic sort, search, filter, or map function accepts a comparison/transformation function and works with any data type. This is the foundation of functional-style programming in Pascal.

  8. Generics are strictly superior to Pointer-based and Variant approaches. They provide the same code reuse with full type safety, better readability, and no manual pointer management. There is no reason to use untyped approaches in new code.

  9. The Repository pattern demonstrates generics at scale. A generic TRepository<T: TEntity> provides CRUD operations for any entity type, eliminating duplicate data access code across the application.

  10. Generics transfer directly to other languages. C++ templates, Java generics, C# generics, and Rust generics all solve the same problem with similar concepts. Learning generics in Pascal prepares you for all of them.