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
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to