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);