Recent

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

duzenko

  • New Member
  • *
  • Posts: 41
Re: Feature announcement: Function References and Anonymous Functions
« Reply #75 on: October 04, 2023, 08:36:29 am »
Hi, is it possible to use an anonymous function with TFPGList.Sort? (And specifically in {$mode delphi}, too)

This does not compile:

Code: Pascal  [Select][+][-]
  1.    procedure FindClose;
  2.    var
  3.       CompareGroup: function(const Item1, Item2: PGroup): Integer;
  4.    begin
  5.       CompareGroup := function(a, b: PGroup): Integer;
  6.       begin
  7.          Result :=  0;
  8.       end;
  9.       ...
« Last Edit: October 04, 2023, 08:40:32 am by duzenko »

bytebites

  • Hero Member
  • *****
  • Posts: 589
Re: Feature announcement: Function References and Anonymous Functions
« Reply #76 on: October 04, 2023, 10:24:42 am »
There is const missing.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5283
  • Compiler Developer
Re: Feature announcement: Function References and Anonymous Functions
« Reply #77 on: October 05, 2023, 09:10:58 pm »
Also you can't access local variables of the outer function in that case, because the Sort method does not take a function reference, but a function pointer and those can't take the state required.

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 832
Re: Feature announcement: Function References and Anonymous Functions
« Reply #78 on: November 10, 2023, 10:21:19 am »
Confusion about closures' functionality and implementation is caused by not understanding their purpose. Their purpose is to define classes without actually defining classes. To do things like this:
Code: Pascal  [Select][+][-]
  1. program Example;
  2.  
  3. type
  4.   TMyProc = reference to procedure;
  5.   TMyClass = record
  6.     MyInc:TMyProc;
  7.     MyDec:TMyProc;
  8.     MyPrint:TMyProc;
  9.   end;
  10.  
  11. function MyConstructor:TMyClass;
  12.   var I:Integer;
  13. begin
  14.   I := 0;
  15.   Result.MyInc := procedure
  16.   begin
  17.     Inc(I);
  18.   end;
  19.   Result.MyDec := procedure
  20.   begin
  21.     Dec(I);
  22.   end;
  23.   Result.MyPrint := procedure
  24.   begin
  25.     WriteLn(I);
  26.   end;
  27. end;
  28.  
  29. var
  30.   MyObject:TMyClass;
  31.  
  32. begin
  33.   MyObject := MyConstructor;
  34.   MyObject.MyPrint();
  35.   MyObject.MyInc();
  36.   MyObject.MyPrint();
  37.   MyObject.MyDec();
  38.   MyObject.MyPrint();
  39. end.
  40.  
But as we don't need such functionality in Pascal, they're usually used to declare callbacks with arbitrary data attached to them. If we need to pass some data to callback, we usually need to mess with declaring some structure or class and passing pointer to it to callback:
Code: Pascal  [Select][+][-]
  1. type
  2.   TData = class
  3.     public
  4.       X, Y, Z:TSomeType;
  5.   end;
  6.  
  7.   procedure AddCallback(AData:Pointer);
  8.   begin
  9.   end;
  10.  
  11. var
  12.   Data:TData;
  13.   X, Y, Z:TSomeType;
  14.  
  15. begin
  16.   Data := TData.Create;
  17.   Data.X := X;
  18.   Data.Y := Y;
  19.   Data.Z := Z;
  20.   SomeProcThatCallsCallback(AddCallback, pointer(Data));
  21.   Data.Free;
  22. end;
  23.  

But things can be made much easier with closures:
Code: Pascal  [Select][+][-]
  1.  
  2. var
  3.   X, Y, Z:TSomeType;
  4.  
  5.   SomeProcThatCallsCallback(
  6.     procedure
  7.     begin
  8.       //Just use X, Y and Z here!
  9.     end
  10.   );
  11.  
Please note, that only global variables can be used in callbacks directly. But global variables aren't always usable. For example they shouldn't be used in thread-safe code. In this case local variables should be used instead. And they can't be used directly. Example:
Code: Pascal  [Select][+][-]
  1. function TList.FilteredCopy(AFilter:TFilter):TList;
  2.   var Temp:TList;
  3. begin
  4.   //As I remember, Result can't be captured, but I can be wrong.
  5.   Temp := TList.Create;
  6.   DoFilter(AFilter,
  7.     procedure(AItem:TItem)
  8.     begin
  9.       Temp.Add(AItem);
  10.     end
  11.   );
  12.   Result := Temp;
  13. end;
  14.  
« Last Edit: November 10, 2023, 10:43:59 am by Mr.Madguy »
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

Warfley

  • Hero Member
  • *****
  • Posts: 1469
Re: Feature announcement: Function References and Anonymous Functions
« Reply #79 on: November 10, 2023, 12:07:19 pm »
Confusion about closures' functionality and implementation is caused by not understanding their purpose. Their purpose is to define classes without actually defining classes. To do things like this:

I would not put it this way, because closures exited long before the concept of Objects existed, the concept comes from Lambda Calculus from the 1930s and even the first implementation in programming languages was in the 60s, long before OOP became a thing.

Rather it is that objects and closures basically try to archive the same goal, associating code with data into one first in class language entity, you can refer to in code, and apply logic and operations on.

The main difference is that in Object the state management is explicit, in the sense that you must explicetly write a class definition containing all the data that will be associated with the functionality, while closures are implicit, where you just write your function, and the data that will be captured will be decided by the compiler from the context.
This means generally that closures allow to have a smaller footprint in the code, but understanding those is much more context dependent, as you do not have one place where all the information is listed.
So typically you would use closures for things which are quite simple and where the effort of writing a class would not add to the understanding, e.g. when it's just a function that is parameterized with very few data elements (e.g. a filter operation where you have a comparator), while usually for more complex thing, e.g. when you have more than one function associated with the data, you would use a class.

amerou

  • Newbie
  • Posts: 1
Re: Feature announcement: Function References and Anonymous Functions
« Reply #80 on: December 04, 2023, 10:18:18 pm »
Is there a timeline when this feature is going to be available?

Thaddy

  • Hero Member
  • *****
  • Posts: 13283
Re: Feature announcement: Function References and Anonymous Functions
« Reply #81 on: December 05, 2023, 09:40:18 am »
As written earlier in the thread, that you obviously did not read, it is already available in trunk. See the first message in this thread and the 7th message in this thread.
« Last Edit: December 05, 2023, 09:48:47 am by Thaddy »
I actually get compliments for being rude... (well, Dutch, but that is the same)

 

TinyPortal © 2005-2018