Re: [fpc-pascal] Working with anonymous functions

2023-03-11 Thread Sven Barth via fpc-pascal

Am 10.03.2023 um 17:34 schrieb Thomas Kurz via fpc-pascal:

Dear all,

I'm testing FPC-trunk and I'm especially interested in using anonymous 
functions because they should simplify working with TThread.Synchronize and 
others a lot.

I stumbled upon an issue which I'd like to post here first because I am not 
sure whether it's a bug or just a wrong usage on my side.

Here's a small example:


program project1;

{$modeswitch anonymousfunctions}
{$modeswitch functionreferences}

uses Classes, EventLog, SysUtils;

type
   TTest = class
 FOnLog: TLogMessageEvent;
 procedure CallOnLog (AEventType: TEventType; AMessage: String);
   end;

procedure TTest.CallOnLog (AEventType: TEventType; AMessage: String);

var
   r: reference to TThreadMethod = nil;


/That/ should not compile. The correct syntax is "reference to function 
..." or "reference to procedure ...".


And the type you're looking for is "TThreadProcedure" which is declared 
as "reference to procedure".



   m: TThreadMethod = nil;

begin
   // This doesn't work because the anonymous procedure is
   // capturing local symbols. I understand that this doesn't work.
   m := procedure
 begin
   FOnLog (Self, AEventType, AMessage);
 end;

   // As far as I have understood
   // https://forum.lazarus.freepascal.org/index.php/topic,59468.0.html
   // the solution should be to use a "reference to".
   // In fact, assignment works as expected:
   r := procedure
 begin
   FOnLog (Self, AEventType, AMessage);
 end;

   // But I seem not to have any change to pass the reference.
   // Both versions fail:
   TThread.ForceQueue (NIL, r());
   TThread.ForceQueue (NIL, @r);
end;

begin
end.


As you can see, the goal is to call TThread.ForceQueue. Of course, the easiest solution 
was having an overloaded "TThread.ForceQueue (TThread, TThreadProcedure)" as is 
the case with Delphi. I have already posted a feature request on Github.


I've added the overload.



But I don't know why I can't use a "reference to TThreadMethod". If I 
understand the feature announcement correctly, this should work, shouldn't it?


That declaration is nonsense, so no, that should definitely not work.

Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Working with anonymous functions

2023-03-10 Thread Thomas Kurz via fpc-pascal
Dear all,

I'm testing FPC-trunk and I'm especially interested in using anonymous 
functions because they should simplify working with TThread.Synchronize and 
others a lot.

I stumbled upon an issue which I'd like to post here first because I am not 
sure whether it's a bug or just a wrong usage on my side.

Here's a small example:


program project1;

{$modeswitch anonymousfunctions}
{$modeswitch functionreferences}

uses Classes, EventLog, SysUtils;

type
  TTest = class
FOnLog: TLogMessageEvent;
procedure CallOnLog (AEventType: TEventType; AMessage: String);
  end;

procedure TTest.CallOnLog (AEventType: TEventType; AMessage: String);

var
  r: reference to TThreadMethod = nil;
  m: TThreadMethod = nil;

begin
  // This doesn't work because the anonymous procedure is
  // capturing local symbols. I understand that this doesn't work.
  m := procedure
begin
  FOnLog (Self, AEventType, AMessage);
end;

  // As far as I have understood
  // https://forum.lazarus.freepascal.org/index.php/topic,59468.0.html
  // the solution should be to use a "reference to".
  // In fact, assignment works as expected:
  r := procedure
begin
  FOnLog (Self, AEventType, AMessage);
end;

  // But I seem not to have any change to pass the reference.
  // Both versions fail:
  TThread.ForceQueue (NIL, r());
  TThread.ForceQueue (NIL, @r);
end;

begin
end.


As you can see, the goal is to call TThread.ForceQueue. Of course, the easiest 
solution was having an overloaded "TThread.ForceQueue (TThread, 
TThreadProcedure)" as is the case with Delphi. I have already posted a feature 
request on Github.

But I don't know why I can't use a "reference to TThreadMethod". If I 
understand the feature announcement correctly, this should work, shouldn't it?

Kind regards,
Thomas

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal