Recent

Author Topic: Feature announcement: Function References and Anonymous Functions  (Read 58648 times)

AFFRIZA 亜風実

  • Full Member
  • ***
  • Posts: 144
Re: Feature announcement: Function References and Anonymous Functions
« Reply #15 on: June 01, 2022, 07:56:54 am »
Nice, can't wait to test that.  :D
Kyoukai Framework: https://github.com/afuriza/kyoukai_framework

Dukung kemerdekaan Donetsk dan Lugansk! Tidak membalas profil berbendera biru-kuning apalagi ber-Bandera.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Feature announcement: Function References and Anonymous Functions
« Reply #16 on: June 01, 2022, 08:54:39 am »
The warnings are on:
testanon.pas(51,1) Warning: (5036) Local variable "$Capturer" does not seem to be initialized
And on line 61 the same.

Can it be that you compile with -O3? (Cause there's another report about this, but without optimizations enabled I can't reproduce this)

Thaddy

  • Hero Member
  • *****
  • Posts: 16184
  • Censorship about opinions does not belong here.
Re: Feature announcement: Function References and Anonymous Functions
« Reply #17 on: June 01, 2022, 10:41:24 am »
I compiled with -O4 and win64. It should be reproducible in main. With -02 there is no warning.
On linux32/64 debian the warning is also there with -O4
Nothing important since the compiler is built with -Sew and -O2 and that gives no warnings.
« Last Edit: June 01, 2022, 10:44:30 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Feature announcement: Function References and Anonymous Functions
« Reply #18 on: June 01, 2022, 01:37:30 pm »
I compiled with -O4 and win64. It should be reproducible in main. With -02 there is no warning.
On linux32/64 debian the warning is also there with -O4

Then, next time, please also mention what settings you use to compile, cause that can make a significant difference.

JdeHaan

  • Full Member
  • ***
  • Posts: 150
Re: Feature announcement: Function References and Anonymous Functions
« Reply #19 on: June 17, 2022, 10:58:09 am »
Hi, first of all, great to have this new functionality and using it already in several places in my code.

I have a small (for me unsolvable) issue, and was hoping to use the function references/anonymous functions to find a solution.
What is the problem? I’m trying to convert a C++ macro to a Pascal function:

#define MEM(allocator, …) (someFunctionCall(), allocator(__VA_ARGS__))

it is called as follows:

MEM(allocString, “Hello world”);
MEM(allocCell, value);
MEM(allocFunction, codeObject);

The result of the MEM call will be a ‘Value’ type.

so, the macro allows to call different functions with different arguments.

The functions are defined as:

Value allocString(std::String string)
Value allocCell(Value value)
Value allocFunction(CodeObject codeObject)

Any idea how to convert this to Object Pascal?

Regards,
Jeroen

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11942
  • FPC developer.
Re: Feature announcement: Function References and Anonymous Functions
« Reply #20 on: June 17, 2022, 12:41:53 pm »
I don't think this is possible. Except maybe with an external macro package like M4.

Macro shenanigans are simply intrinsicly unportable between languages as they operate on the text of the code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Feature announcement: Function References and Anonymous Functions
« Reply #21 on: June 17, 2022, 01:24:53 pm »
Any idea how to convert this to Object Pascal?

Under the assumption that the allocators only take one argument you can do it like this (this requires main due to the implicit function specialization):

Code: Pascal  [Select][+][-]
  1. program ttest;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch implicitfunctionspecialization}
  5.  
  6. type
  7.   Value = record
  8.   end;
  9.  
  10.   generic TAllocator<T> = function(const aArg: T): Value;
  11.  
  12. procedure SomeFunctionCall;
  13. begin
  14.  
  15. end;
  16.  
  17. generic function MEM<T>(allocator: specialize TAllocator<T>; const aValue: T): Value; inline;
  18. begin
  19.   SomeFunctionCall;
  20.   Result := allocator(aValue);
  21. end;
  22.  
  23. function AllocString(const aStr: String): Value;
  24. begin
  25. end;
  26.  
  27. function AllocCell(const aCell: Value): Value;
  28. begin
  29. end;
  30.  
  31. function AllocFunction(const aCodeObject: CodePointer): Value;
  32. begin
  33. end;
  34.  
  35. var
  36.   v: Value;
  37. begin
  38.   v := MEM(@AllocString, 'Hello World');
  39.   v := MEM(@AllocCell, v);
  40.   v := MEM(@AllocFunction, CodePointer(@SomeFunctionCall));
  41. end.

At least assuming I understood correctly what you're trying to do...

JdeHaan

  • Full Member
  • ***
  • Posts: 150
Re: Feature announcement: Function References and Anonymous Functions
« Reply #22 on: June 17, 2022, 02:11:59 pm »
Yes, that's pretty much what I need, thanks, I'll give it a try!
So, nothing to do with function references, as mentioned in the new feature...

Ryan J

  • Full Member
  • ***
  • Posts: 138
Re: Feature announcement: Function References and Anonymous Functions
« Reply #23 on: June 19, 2022, 05:56:58 am »
Quote
Under the assumption that the allocators only take one argument you can do it like this (this requires main due to the implicit function specialization):

Firstly I just joined the forum and I couldn't figure out how to reply by quoting selected text. Is this possible?

I just actually posted this exact same question on the FPC mail list before I saw this post. So it works with only one argument but why are arguments not allowed? The type is an undefined generic so it should work in theory and only consider the parameters when the function is specialize

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Feature announcement: Function References and Anonymous Functions
« Reply #24 on: June 19, 2022, 01:12:13 pm »
Quote
Under the assumption that the allocators only take one argument you can do it like this (this requires main due to the implicit function specialization):

Firstly I just joined the forum and I couldn't figure out how to reply by quoting selected text. Is this possible?

You just did?

I just actually posted this exact same question on the FPC mail list before I saw this post. So it works with only one argument but why are arguments not allowed? The type is an undefined generic so it should work in theory and only consider the parameters when the function is specialize

It's possible for more arguments as well, but it means that you need to add overloads of MEM that uses different types of function variables. E.g. like this:

Code: Pascal  [Select][+][-]
  1. type
  2.   generic TAllocator1<T1> = function(const aArg1: T1): Value;
  3.   generic TAllocator2<T2> = function(const aArg1: T1; const aArg2: T2): Value;
  4.  
  5. generic function MEM<T1>(allocator: specialize TAllocator1<T1>; const aValue1: T1): Value; inline;
  6. generic function MEM<T1, T2>(allocator: specialize TAllocator2<T1, T2>; const aValue1: T1; const aValue2: T2): Value; inline;

Ryan J

  • Full Member
  • ***
  • Posts: 138
Re: Feature announcement: Function References and Anonymous Functions
« Reply #25 on: June 20, 2022, 04:47:23 am »
For quoted reply I could copy and pasted but notice how it doesn't say who the quote was from. I expected to select some text and then hover the mouse over it and have an option to quote the selection. Pressing the quote button quotes the entire message which I think need to edit by hand.

The question was more about the undefined type and adding parameters like:

Code: Pascal  [Select][+][-]
  1. generic procedure Perform<T>(func: T);
  2. begin
  3. func(1);
  4. end;

I replied and CC'd you on the mail list also since we're both having problems getting messages. I'm using a gmail account btw because my private domain was blocked (Jonas discovered this some years ago) but I think that's our problem. Other users reported this also so maybe Gmail is the culprit for them also.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Feature announcement: Function References and Anonymous Functions
« Reply #26 on: June 20, 2022, 01:36:24 pm »
For quoted reply I could copy and pasted but notice how it doesn't say who the quote was from. I expected to select some text and then hover the mouse over it and have an option to quote the selection. Pressing the quote button quotes the entire message which I think need to edit by hand.

Correct. You quote whole and then edit by hand.

The question was more about the undefined type and adding parameters like:

Code: Pascal  [Select][+][-]
  1. generic procedure Perform<T>(func: T);
  2. begin
  3. func(1);
  4. end;

Then you should have mentioned that in the first place, cause I thought you were referring to what I had written to JdeHaan.

I replied and CC'd you on the mail list also since we're both having problems getting messages. I'm using a gmail account btw because my private domain was blocked (Jonas discovered this some years ago) but I think that's our problem. Other users reported this also so maybe Gmail is the culprit for them also.

It has something to do with SPF records and the domain we send e-mails from. We're already trying to solve this, but as documentation is a bit sparse it's a bit hit-and-miss.

JdeHaan

  • Full Member
  • ***
  • Posts: 150
Re: Feature announcement: Function References and Anonymous Functions
« Reply #27 on: June 21, 2022, 10:16:04 pm »
Again thank you PascalDragon for the examples. I did need 1 or 2 arguments. Above that I needed it to be part of an advanced record. The following code runs now perfectly:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. {$ModeSwitch advancedrecords}
  3. {$ModeSwitch implicitfunctionspecialization}
  4.  
  5. type
  6.   generic TAllocator1<T1> = function(const aArg1: T1): TValue;
  7.   generic TAllocator2<T1, T2> = function(const aArg1: T1; const aArg2: T2): TValue;
  8.  
  9.   TMyRec = record
  10.     procedure someProc;
  11.     generic function MEM<T1>(allocator: specialize TAllocator1<T1>;
  12.       const aValue1: T1): TValue;
  13.     generic function MEM<T1, T2>(allocator: specialize TAllocator2<T1, T2>;
  14.       const aValue1: T1; const aValue2: T2): TValue;
  15.   end;
  16.  
  17. implementation
  18.  
  19. generic function TMyRec.MEM<T1>(allocator: specialize TAllocator1<T1>;
  20.   const aValue1: T1): TValue;
  21. begin
  22.   someProc;
  23.   Result := allocator(aValue1);
  24. end;
  25.  
  26. generic function TMyRec.MEM<T1, T2>(allocator: specialize TAllocator2<T1, T2>;
  27.   const aValue1: T1; const aValue2: T2): TValue;
  28. begin
  29.   someProc;
  30.   Result := allocator(aValue1, aValue2);
  31. end;
  32.  

and then calling the respective MEM functions with 1 or 2 arguments from other functions in the record:

Code: Pascal  [Select][+][-]
  1. Result := MEM(@allocString, 'Hello world!');
  2. Result := MEM(@allocCell, Value);
  3.  
  4. Result := MEM(@allocFunction, Name, Arity);
  5.  

Really nice feature!

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Feature announcement: Function References and Anonymous Functions
« Reply #28 on: June 22, 2022, 09:01:59 am »
Really nice feature!

You're welcome.

Please note that you need the ImplicitFunctionSpecialization modeswitch only in the unit where you call MEM, not where you declare it (I know you said that you call MEM from other methods of the same record, so for your real code this doesn't apply, but I just wanted to be sure that you're aware of this).

JdeHaan

  • Full Member
  • ***
  • Posts: 150
Re: Feature announcement: Function References and Anonymous Functions
« Reply #29 on: June 22, 2022, 12:25:09 pm »
Noted, thanks!

 

TinyPortal © 2005-2018