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