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.

--
βþ
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to