[fpc-devel] Functors
Michael Van Canneyt
michael at freepascal.org
Sun Dec 26 09:50:40 CET 2021
On Sun, 26 Dec 2021, Blaise--- via fpc-devel wrote:
> I propose that the support for https://en.wikipedia.org/wiki/Function_object
> be added to the FPC.
Please explain what's the point or benefit of this.
None of what is shown below cannot be handled by ordinary methods, and I
find the resulting code aC(33) more confusing than anything else.
As I see it, it's just shorthand syntax to allow skipping the name 'Invoke'.
If that is all it is, then I think the idea is overly complicated and can be
achieved simply by the mechanism used by default array properties:
To reuse your example:
Type
C = class(TObject)
function Add9(const N: Integer): Integer; default;
end;
var
aC : C;
begin
aC:=C.Create;
Writeln(ac(33));
end;
I think the idea of using a fixed member identifier for special purposes is really
stupid design. I'll never forgive Embarcadero their 'GetEnumerator' idea...
Michael.
>
> A subset of such functionality already existed as a part of my implementation
> of closures, so I extended that part to implement the core feature for
> allowing functors -- overloading of the call operator: when round brackets
> are applied to an instance of a record, object/class, or interface type, they
> are translated into a call to the method Invoke of that instance. The
> attached proof-of-concept functors-1.patch allows the following test case to
> be compiled:
> -------8<-------
> type I = interface
> procedure Invoke;
> end;
>
> type C = class(TInterfacedObject, I)
> class function Invoke(const N: Integer): Integer; overload;
> procedure Invoke; overload;
> end;
> class function C.Invoke(const N: Integer): Integer;
> begin
> result := N + 9
> end;
> procedure C.Invoke;
> begin
> writeln(ClassName, '.Invoke')
> end;
>
> type H = class helper for C
> procedure Invoke(const S: string); overload;
> end;
> procedure H.Invoke(const S: string);
> begin
> writeln('H.Invoke("', S, '")')
> end;
>
> var aC: C;
> var anI: I;
> begin
> aC := C.Create;
> writeln( aC(33) );
> aC('hello');
>
> anI := aC;
> anI()
> end.
> -------8<-------
> Important design points:
> 1) Applying round brackets to instances does not collide with the existing
> syntax;
> 2) Naturally, helpers are able to turn helpees into functors;
> 3) Operator () cannot be applied to types -- that would clash with explicit
> type conversions;
> 4) Explicit empty argument lists are required -- unorthogonal to routines and
> procedural variables, but clarity must win here;
> 5) {$modeswitch Closures} is required (modeswitch_closures.patch from
> https://lists.freepascal.org/pipermail/fpc-devel/2021-December/044261.html)
> -- functors are closure-adjacent in the area of functional programming.
>
> The parts that are currently missing:
> 1) Implicit conversion from functors to method pointers -- should be fairly
> trivial to implement;
> 2) Support for generics -- should be straightforward as well;
> 3) The OPERATOR keyword instead of PROCEDURE/FUNCTION for methods Invoke --
> should we choose to require it -- would be somewhat more complicated.
>
> --
> βþ
>
More information about the fpc-devel
mailing list