The Free Pascal Language

Free Pascal is a compiled, strongly typed, modern, object oriented programming language. It has largely maintained compatibility with the various revisions of Delphi, a programming language originally designed by Anders Hejlsberg in the early 1990’s. When Anders Hejlsberg left Borland to join Microsoft in the late 1990's, his history with Delphi clearly influenced his design of the C# programming language. C# may have popularizing programming concepts such as event types, properties, reflection, and object querying, but they were all features of Delphi first.

What’s new in Free Pascal

The most recent version of Free Pascal is 3.0. It supports constructs such as generic programming with type constraints, iterators and enumerators, user definable conversions, value types with properties methods and events, extension methods, and more. Read below to learn more.

Generics and constraints

All complex types can now use generics. Complex types include classes, records, interfaces, arrays, events and functions. Constraints such as class, record, constructor, or types can be specified.
type
  TTradeInVehicle<T> = function(UsedVehicle: T): T;

  TEmployee<T: TVehicle, constructor> = class
  private
    FVehicle: T;
    FTradeIn: TTradeInVehicle<T>;
    procedure SetTradeIn(Value TTradeInVehicle<T>);
  public
    { Every employee has a company vehicle and can request to trade it in }
    property Vehicle: T read FVehicle;
    property TradeIn: TTradeInVehicle<T> read FTradeIn write SetTradeIn;
  end;

  TMailman = class(TEmployee<TDeliveryTruck>)
    { A mailman always has a delivery truck }
  end;

  TChiefExecutiveOfficer<T: TLuxurySedan, constructor> = class(TEmployee<T>)
    { While the CEO still has a choice of stylish rides }
  end;

  { Declare a type alias, see section on existing language features }
  THeadOfState = TChiefExecutiveOfficer<TBulletProofLimousine>;

Iterators and enumerators

Many types now have built in support for iterators. With the addition of enumerators you may also add iterator support to your own types.
  for Employee in Company.Employees do
    Assets += Employee.Vehicle.CurrentValue;

{ Or perhaps }

  for Employee in Email.Recipients do
    Email.CarbonCopy(Employee.Supervisor);
  Email.Send;

Object type functionality on records

Record types (equivalent to struct or value types in C/C#), records can now have the same functionality as classes. This includes putting properties, and methods on records.
type
  TVector2 = record
  private
    FX: Single;
    FY: Single;
  public
    constructor Create(X, Y: Single);
    procedure Move(X, Y: Single);
    property X: Single read FX write FX;
    property Y: Single read FY write FY;
  end;

{ And then }

  VectorA := TVector2.Create(3.5, 7.1); // constructor on a value type
  VectorA.Move(4.9, 0.3);               // a method which modifies a value type

Operator overloading and user defined conversions

Both class and record types allow for both operator overloading and user defined conversions. Continuing with the example in the previous section, we can define operators which allow vectors to be added or subtracted from one another, and conversions to between vectors and points.
type
  TVector2 = record
    class operator Add(const A, B: TVector2): TVector2;
    class operator Subtract(const A, B: TVector2): TVector2;
    class operator Implicit(const P : TPoint): TVector2;
    class operator Explicit(const V : TVector2): TPoint;
  end;

{ And then }

  VectorA := Bounds.TopLeft;     // implicit conversion from TPoint to TVector2 
  VectorB := Bounds.BottomRight; // no data is lost on an implicit conversion 
  VectorC := VectorA + VectorB;  // operator overloading
  PointA := TPoint(VectorC);     // an explicit conversion is invoked

Extension methods and properties

Both class and record types can be extended through helper objects. Helper types can add methods and properties to a type.
type
  TVector2Helper = record helper for TVector2
  private
    function GetMagnitude: Single;
  public
    procedure Swing(Direction: TVector2; Club: TGolfClub; PowerLevel: Single);
    function Distance(const V: TVector2): Single;
    property Magnitude: Single read GetMagnitude;
  end;

{ And then }

  WriteLn('The distance between Tiger and Phil opening golf drives: ', TigerBall.Distance(PhilBall));
  WriteLn('The Tiger opening drive distance: ', TigerBall.Magnitude);

Dotted namespace support

While Free Pascal units have always acted like their own namespace, you can now use multiple namespace identifiers in a single unit name.
unit Company.Network.Storage;

interface

uses
  Company.Security,
  Company.Security.Encryption,
  Company.Compression.Lzo,
  { Add more namespaces here }

See also