[fpc-pascal] Caller agnostic procedure variables

Michael Van Canneyt michael at freepascal.org
Tue Feb 15 09:32:27 CET 2022



On Tue, 15 Feb 2022, Ryan Joseph via fpc-pascal wrote:

>
>
>> On Feb 15, 2022, at 2:09 PM, Michael Van Canneyt via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
>> 
>> I've answered this question before:
>> 
>> The "Reference to procedure" that will be part of anonymous functionswill do this for you.
>
> I'm sorry I forgot! This thing keeps coming up for me and driving me nuts but I knew I asked in passing before.
>
> So "reference to procedure" are going to be the new standard?

I don't know what you mean by 'new standard', but a new type, yes.

We're not going to change all procedural types to this new type, if that's
what you have in mind.

> To extend
> my example it would look like this?  I please remind me, is there a
> closure involved which is capturing state and adding overhead?

There is not necessarily a closure; only if you use an anonymous function.

>
> I'm curious what this type actually is also, maybe a dispatch table which wraps the existing types or is it something totally new?

I will leave it to the compiler people to answer this, because I don't know
the low-level details.

>
> ====================
>
> type
>  TMyAction = reference to procedure;
>
> procedure DoThis(action: TMyAction);
>  begin
>    action();
>  end;

Yes. The following compiles and runs in delphi:

program procdemo;

{$APPTYPE CONSOLE}

{$R *.res}

Type
   TProc = reference to procedure;

   TMyObject = Class
     Procedure DoA;
     Procedure DoTest(aTest : TProc);
     Procedure Demo;
   End;

Procedure DoPlain;

begin
   Writeln('Plain');
end;

{ TMyObject }

procedure TMyObject.Demo;
begin
   DoTest(DoA);
   DoTest(DoPlain);
   DoTest(Procedure
    begin
      Writeln('anonymous');
    end);
end;

procedure TMyObject.DoA;
begin
   Writeln(ClassName,': A');
end;

procedure TMyObject.DoTest(aTest: TProc);
begin
   aTest;
end;

begin
   With TMyObject.Create do
     try
       Demo;
     finally
       Free;
     end;
end.

I requested that this:

procedure TMyObject.Demo;

   Procedure DoSub;
   begin
     Writeln('Sub');
   end;

begin
   DoTest(DoSub);
end;

would also work. It does not work in Delphi, but Pas2js already supports that. 
I think it results in more readable code - the whole anonymous stuff doesn't really work for me...

Michael.


More information about the fpc-pascal mailing list