[fpc-announce] Feature announcement: Generic functions, procedures and methods

Sven Barth pascaldragon at googlemail.com
Sat Nov 21 18:32:32 CET 2015


Hello together!

I'm pleased to finally announce the addition of generic functions, 
procedures and methods (collectively called "routines") to Free Pascal 
which allows writing type safe methods that can be used for multiple types.

Syntax:

The syntax for declaring a generic routine is similar to declaring a 
normal routine and also includes support for class methods:

generic [class] (procedure|function) 
IDENTIFIER<TYPEARGLIST>[(PARAMETERLIST)][: RESULTTYPE]; MODIFIERS;

For the TYPEARGLIST the same rules apply as for generic types. Type 
parameters declared in the TYPEARGLIST might be used in the 
PARAMETERLIST, the RESULTTYPE and of course the body of the routine.

Generic routines can be overloaded both by TYPEARGLIST and PARAMETERLIST.

To call a generic routine you use the following syntax:

specialize IDENTIFIER<TYPELIST>[(PARAMETERS)]

For the TYPELIST the same rules apply as for specializing a generic type.
If the routine is part of a type or variable or you're using a unit
name to distinguish a generic routine you need to put that before the 
"specialize":

TYPENAME.specialize IDENTIFIER<TYPELIST>[(PARAMETERS)]
VARIABLE.specialize IDENTIFIER<TYPELIST>[(PARAMETERS)]
UNITNAME.specialize IDENTIFIER<TYPELIST>[(PARAMETERS)]

Calls to generic routines are normal factors so they can be used as such 
as the following example shows:

=== example begin ===

{$mode objfpc}

generic function Add<T>(aLeft, aRight: T): T;
begin
   Result := aLeft + aRight;
end;

begin
   Writeln(specialize Add<String>('Generic ', 'routines') + specialize 
Add<String>(' with ', 'Free Pascal'));
end.

=== example end ===

Delphi compatibility:

Of course this future is also implemented in a Delphi-compatible way for 
the Delphi modes. There the syntax for declaring a generic function is 
like this:

[class] (procedure|function) IDENTIFIER<TYPELIST>[(PARAMETERLIST)][: 
RETURNTYPE]; MODIFIERS;

So merely the "generic" keyword is missing. This is analogous when 
calling a generic routine:

IDENTIFIER<TYPELIST>[(PARAMETERS)]

Because of the missing "specialize" keyword that mark specializations 
complex expressions *do not* work in mode Delphi yet. So assignments of 
function results are okay, but other than that you'll likely encounter 
compiler errors.

Please note that unlike Delphi we *do* support global generic 
functions/procedures even in Delphi mode.

Limitations/ToDos:

The feature is not yet finished and there are some limitations that yet 
need to be overcome or parts that simply don't work yet, this includes, 
but is not necessarily limited to:

- support for complex expressions in Delphi modes (applies to type 
specializations as well)
- support for pointers to generic routines (this will currently result 
in errors at the best case and internal errors or exceptions at the worst)
- support for the return value in modes without support for "Result"
- support for nested generics, most importantly generic methods inside 
generic classes

So please test and report any bugs in the bug tracker. Questions can of 
course be asked here on the mailing list (no, this feature won't be part 
of FPC 3.0.0).

Regards,
Sven


More information about the fpc-announce mailing list