[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