[fpc-pascal] Re: [fpc-announce] Feature announcement: Type helpers

Gerhard Scholz gs at g--s.de
Fri Feb 8 00:30:32 CET 2013


I tried to compile the example:

   TLongIntHelper = type helper for LongInt
     class procedure Test; static;

class procedure TLongIntHelper.Test;

   i: LongInt;


G:\ob\syncdirs>ppc386 -vv -al -CioOrt -Cs6000000  -gclt -Mobjfpc -O1 -OpPENTIUM 
 -Fuu:\ -FuM:\u -FuC:\c\-u -FiC:\c\-u -Fuz:\-u -Fiz:\-u -FuP:\gs\tp55\includes 
 -Fuf:\-u -Fiu:\ -FiM:\u -FiP:\gs\tp55\includes -Fif:\-u -FE. 
thelper.pas(2,33) Error: Identifier not found "helper"
thelper.pas(2,33) Error: Error in type definition
thelper.pas(2,33) Error: Can't create unique type from this type
thelper.pas(2,33) Fatal: Syntax error, ";" expected but "FOR" found
Fatal: Compilation aborted

The compiler is freshly generated from the SVN

Does the compiler expect special options to invoke the record helper 


----- Original Message ----- 
From: "Sven Barth" <pascaldragon at googlemail.com>
To: <fpc-announce at lists.freepascal.org>
Cc: <fpc-pascal at lists.freepascal.org>; "FPC developers' list" 
<fpc-devel at lists.freepascal.org>
Sent: Wednesday, February 06, 2013 10:49 AM
Subject: [fpc-announce] Feature announcement: Type helpers

> Hello Free Pascal community!
> I'm pleased to announce the addition of type helpers which extend the 
> existing helper concept with the ability to extend primitive types.
> Motivation:
> With class and record helpers the possibility was created to extend 
> classes and records with types without subclassing the type (which 
> wouldn't be possible with records anyway). This allows to add e.g. methods 
> to types in units that you can't influence or where you can't influence 
> with type is instantiated (e.g. the TStrings descendant used in TMemo). 
> Now it is logical to extend this also to other types supported by Pascal, 
> but here more driven by the possibility to group methods together and have 
> them appear to belong to the primitive type.
> While this does not bring the concepts of boxing of managed 
> languages/environments like Java and .NET to Pascal it does nevertheless 
> look this way.
> Syntax:
> The declaration of type helpers looks as follows:
> end;
> Like class and record helpers they support all visibility sections and you 
> can define methods, properties and constructors. Inside methods declared 
> in the helper "Self" will be of the extended type's type and it's value 
> can also be changed.
> Similar to record helpers class methods MUST be declared as static.
> Usage:
> A type helper is active if it is in scope. This means it must either have 
> been declared in the same unit before the code which wants to use the 
> helper or it needs to be declared in a used unit. As with class and type 
> helpers only one helper for a given type can be active and thus you need 
> to keep in mind the scoping rules when using helpers (e.g. the current 
> unit is searched in the order implementation section then interface 
> section (if the code is in the implementation section) and then the used 
> units are searched from right to left and each unit from top to bottom).
> In some cases the meaning of a type depends on the compiler settings the 
> helper is compiled with. E.g. the type Integer is either a ShortInt or a 
> LongInt depending on the current mode (fpc/tp vs. objfpc/delphi) and the 
> type String is different depending on the switches {$H+/-} and 
> {$modeswitch unicodestring}. This needs to be kept in mind when working 
> with these "generic" types. Another special case is the type Extended on 
> platforms that don't support that type (and thus it will be defined as 
> Double).
> Additionally a type declared as "NewType = type OldType" is considered a 
> completly independant type as it is the case with e.g. operator overloads 
> as well.
> If a helper for the type is in scope you can simply invoke it's methods or 
> properties like you'd do on classes or records. Let's suppose we have a 
> helper with method "ToString: String" for the type LongInt in scope then 
> it will look like this:
> === example begin ===
> var
>   i: LongInt;
> begin
>    Writeln(i.ToString);
> end.
> === example end ===
> Additionally to invoking type helpers on variables they can also be used 
> on constants though special care needs to be taken that the correct type 
> is used. E.g. the constant "200" will be handled as a "Byte" whereas "20" 
> will be handled as "SmallInt". Also the type of string constants depends 
> on the current mode switch (especially {$H+/-} and {$modeswitch 
> unicodestring}) and also the content of the string. E.g. in case of 
> "{$mode objfpc}{$H+}" a string containing unicode characters will be 
> handled as a UnicodeString constant and thus only helpers for 
> UnicodeString will apply.
> For the following example let's assume the helper from the previous 
> example is in scope again:
> === example begin ===
> begin
>   Writeln($12345678.ToString);
> end.
> === example end ===
> Additionally addresses (e.g. "@i") (type: Pointer) and the built in 
> constants "True" (type: Boolean), "False" (type: Boolean) and "Nil" (type: 
> Pointer) are allowed as well. Please note that in the case of typed 
> addresses also the untyped pointer type will be used, because a 
> corresponding typename might not be available to the current unit (and 
> thus the helper could not be found). Constants that can't be used with 
> type helpers are set and array constructors.
> Class methods (and properties) can be either used on variables or 
> constants, but also on the type name itself:
> === example begin ===
> type
>   TLongIntHelper = type helper for LongInt
>     class procedure Test; static;
>   end;
> class procedure TLongIntHelper.Test;
> begin
>   Writeln('Test');
> end;
> var
>   i: LongInt;
> begin
>   i.Test;
>   $12345678.Test;
>   LongInt.Test;
> end.
> === example end ===
> Supported types:
> There is a restrictions on the type which can be extended. Basically every 
> primitive type is allowed besides the following:
> * file types (TextFile, file of ...)
> * procedural variables
> Of course types like records, classes, Objective C classes, C++ classes, 
> objects and interfaces are forbidden as well.
> Viewed from the other perspective this means that the following types are 
> allowed:
> * ordinal types
> * string types (including char types)
> * set and enum types
> * array types
> * boolean types
> * Variant
> * floating point types
> * pointer types
> Delphi compatibility:
> This feature was introduced by Delphi XE3, but instead of using the more 
> logical "type helper" syntax they added support for primitive types to the 
> "record helper" one. Thus to keep Delphi compatibility this is also the 
> syntax used in mode Delphi. Also in non Delphi modes inheritance for 
> helper types is supported.
> Future developments:
> Add support for more types, especially interface and object types. They 
> will either be added as class helpers or as "object helper" and "interface 
> helper" (as objects and interfaces support inheritance the scoping rules 
> inside the helper will resemble class helpers more than record/type 
> helpers).
> Allow that multiple helpers are active for one type at a single time. This 
> is one of the main restrictions of the current helper implementation. For 
> this corresponding lookup rules need to be defined and the feature will be 
> added as a modeswitch (maybe by default enabled in mode objfpc).
> Add support for helpers to the JVM target. The most likely implementation 
> approach is to pass the "Self" value as an additional parameter and treat 
> the methods otherwise as static ones (like is done in .NET for helper 
> methods).
> Regards,
> Sven
> _______________________________________________
> fpc-announce maillist  -  fpc-announce at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-announce 

More information about the fpc-pascal mailing list