[fpc-devel] 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-devel
mailing list