Language & Libraries

From Anonymous Methods and Generics to Inline Variables: Modern Object Pascal features you should be using.

Evolving with Modern Object Pascal

Delphi and C++Builder have been foundational tools for enterprise application development for nearly three decades. As a result, many codebases have remained largely untouched at the core language level, which is a testament to the stability of the platform. "If it isn't broken, don't fix it" is a prudent business strategy.

However, remaining statically on older language syntax carries an invisible cost. Modern language features aren't just syntactic sugar; they are designed to improve code stability, reduce memory leaks, simplify complex logic, and prepare the application for architecture changes. Furthermore, as you begin updating 3rd-party libraries, you will inevitably encounter newer language constructs. Understanding and using these features early makes your migration smoother and increases the long-term maintainability of your core intellectual property.

When to prioritise language updates

  • When you are already modifying code for Unicode, 64-bit, or FireDAC migration.
  • When bringing in frameworks (REST, FMX, RAD Server) that rely on modern constructs.
  • When the team is fighting duplicated boilerplate or manual memory management issues.

The Delphi language has changed significantly starting around 2009. Here are the core modern language features you should be using in your upgraded applications.

Anonymous Methods

Before 2009, every method had to have a name, and it was impossible to compile code containing a procedure or function that lacked one. This changed with the introduction of Anonymous Methods. You can now embed and assign a nameless method directly to a method pointer variable, or pass it as an argument to other methods. This is incredibly useful for inline event handling and asynchronous callbacks.

type
  TFuncOfInt = reference to function(x: Integer): Integer;
...
function MakeAdder(y: Integer): TFuncOfInt;
begin
  Result := { start anonymous method } function(x: Integer) : Integer
  begin
    Result := x + y;
  end; { end anonymous method }
end;

Anonymous Methods in Delphi

Anonymous methods and Closures are related but distinct concepts. All Closures are Anonymous methods, but not all Anonymous methods capture state.

docwiki.embarcadero.com

Generics

Generics represent one of the most widely used modern features. A generic is a data object whose specific type is determined at the point of instantiation rather than declaration. This allows you to write type-safe, highly reusable collections and algorithms without duplicating code or relying on unsafe Pointer casting.

type
  TPair<TKey,TValue> = class
  private
    FKey: TKey;
    FValue: TValue;
  public
    property Key: TKey read FKey write FKey;
    property Value: TValue read FValue write FValue;
  end;

// Instantiated types
type
  TSIPair = TPair<String,Integer>;
  TSSPair = TPair<String,String>;

Overview of Generics

Do not confuse Generics with Variants. A Generic changes the strongly typed declaration at compile time; a Variant holds different values dynamically at runtime.

docwiki.embarcadero.com

RTTI and Custom Attributes

Attributes are metadata tags attached to your code (classes, methods, properties) at design time that can be read dynamically at runtime using Extended RTTI (Run-Time Type Information), your application can "reflect" upon itself at runtime to discover these tags.

This is the engine behind modern Delphi features like JSON/REST serialization and ORM frameworks. Beyond simple data inspection, Extended RTTI allows you to invoke methods dynamically and manipulate objects without needing static links at compile time.

type
  // Custom attribute definition
  MyCustomAttribute = class(TCustomAttribute);

  [MyCustomAttribute]
  TSomeClass = class
  public
    [MyCustomAttribute]
    procedure Work;
  end;

Attributes (RTTI)

Learn how custom attributes are declared and consumed through RTTI to drive serialization, validation, and framework behavior.

docwiki.embarcadero.com

Implicit Unicode

Unicode has been standard in RAD Studio for many years, and most projects already benefit from implicit handling in everyday code. The key point for language modernization is understanding where text boundaries exist (API calls, file I/O, and external systems) so that updated libraries and newer code patterns remain predictable.

For a focused migration checklist, read the dedicated Unicode Migration guide.

Class and Record Helpers

Class and Record Helpers are incredibly powerful tools for avoiding vast inheritance trees. They allow you to dynamically "attach" new methods to an existing class or record, even ones you don't own (like VCL controls or RTL classes), without subclassing them.

type
  TMyClassHelper = class helper for TMyClass
    procedure HelloWorld;
    function MyFunc: Integer;
  end;

Class and Record Helpers (Delphi)

Official syntax, scoping rules, and best practices for using helpers safely in production code.

docwiki.embarcadero.com

Data Type Helpers

Taking the concept of Record Helpers further, Delphi allows you to extend primitive data types (like Int, String, Boolean). The RTL is heavily built on this today (e.g., TStringHelper, TIntegerHelper).

var
  MyString: string;
begin
  MyString := 'This is a string.';
  // Using zero-based string helper method natively on the primitive
  Writeln(MyString.IndexOf('a'));
end;

System.SysUtils.TStringHelper

Reference for core string helper methods that make text parsing and manipulation far cleaner than legacy utility code.

docwiki.embarcadero.com

Inline Variables

Introduced in 10.3 Rio, inline variable declaration shifted a fundamental paradigm of strict Pascal. Instead of declaring all variables at the top of a routine in a var block, you can declare them exactly where they are needed. Because their scope is restricted to the specific local block (e.g., inside a begin..end of a loop), they force cleaner code structure and help the compiler optimize memory management.

procedure ProcessItems(const Items: TArray<string>);
begin
  for var I := 0 to High(Items) do
  begin
    var CurrentItem := Items[I];
    Writeln(Format('%d: %s', [I, CurrentItem]));
  end;
  // CurrentItem is not visible here because it was declared inside the loop block.
end;

Inline Variable Declaration

Language reference for inline variable syntax, block scope, type inference behavior, and compiler rules.

docwiki.embarcadero.com

Expanding Your Application's Capabilities

Once your core code is compiling and taking advantage of modern language constructs, the broader RAD Studio ecosystem opens up natively to your application:

  1. Cross-Platform Delivery (FMX): Take your strict business logic and deploy it across Windows, macOS, Linux, iOS, and Android using the FireMonkey framework from a single codebase.
  2. Parallel Programming Library (PPL): Implement multi-threaded tasks, asynchronous methods, and parallel For loops without managing raw OS thread handles.
  3. Cloud and Service Delivery: Wrap existing Delphi logic as REST services, including serverless-style and API-first deployment approaches.
  4. FireDAC: Standardize data access across multiple backends through a single, modern data layer.
  5. Python4Delphi: Access thousands of Python packages (like TensorFlow, PyTorch) directly within your Delphi UI, bridging native CPU performance with Python's AI/ML ecosystem.
  6. RAD Server: Expose modernized business logic as secure APIs for web and mobile consumers.
  7. AWS and Azure SDKs: Integrate cloud storage and platform services directly into native applications.

Using the Parallel Programming Library

Guide to task-based parallelism, async patterns, and parallel loops in Delphi.

docwiki.embarcadero.com

FireDAC for RAD Studio

Overview of high-performance, unified database access for enterprise Delphi and C++Builder applications.

www.embarcadero.com

Going Serverless with Delphi

Practical guidance for delivering Delphi business logic in cloud-native service architectures.

learndelphi.org

Getting Started with Python4Delphi

Introductory guide for embedding Python in Delphi applications and using Python packages from native projects.

blogs.embarcadero.com

Microsoft Azure Blob API

Reference for using Azure Blob storage APIs from RAD Studio projects.

docwiki.embarcadero.com

Python4Delphi Videos

https://youtu.be/qEcVW4EKGkg

Deepstack face recognition example in Delphi using Python integration workflows.

https://www.youtube.com/watch?v=q3tUhXrHHGc

CodeProject object recognition demo showing practical AI integration patterns in Delphi.

Ready to take the next step?

Our migration specialists have helped thousands of Delphi and C++Builder developers modernize their legacy architecture safely and efficiently.