[fpc-pascal] Caller agnostic procedure variables
Ryan Joseph
genericptr at gmail.com
Tue Feb 15 08:06:15 CET 2022
This has been a constant problem for me with FPC and wanted to make a formal post with code examples since I've only mentioned it in passing before.
How can it be achieved to have a caller agnostic procedure variables? I've tried making some big crazy dispatch record that uses generics but because generics don't support variable templates (like some languages have TClass<T...>) it was limited and clunky to use.
The problem is that from the perspective of the receiver it shouldn't really care what the caller has provided except for that there is a procedure that needs to be called. For example if there is a "sort" function that takes a procedure variable it shouldn't care if the procedure is a global function, a method or a nested function (and eventually a closure).
It feels like the compiler needs a new type which encapsulates these different types but I'm not sure how this all works internally. Any thoughts on this?
===========================
{$mode objfpc}
program procvars;
type
TMyAction = procedure;
TMyClass = class
procedure MyAction;
end;
procedure DoThis(action: TMyAction);
begin
action();
end;
procedure MyAction;
begin
end;
procedure Test;
procedure MyNestedAction;
begin
end;
var
c: TMyClass;
begin
// of object
c := TMyClass.Create;
DoThis(@c.MyAction); // error: Incompatible type for arg no. 1: Got "<procedure variable type of procedure of object;Register>", expected "<procedure variable type of procedure;Register>"
// is nested
DoThis(@MyNestedAction); // error: Incompatible type for arg no. 1: Got "<procedure variable type of procedure is nested;Register>", expected "<procedure variable type of procedure;Register>"
// normal
DoThis(@MyAction);
end;
begin
end.
Regards,
Ryan Joseph
More information about the fpc-pascal
mailing list