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