[fpc-devel] Nested function closures

Sven Barth pascaldragon at googlemail.com
Tue Apr 27 20:10:08 CEST 2021

Am 27.04.2021 um 17:58 schrieb Michael Van Canneyt via fpc-devel:
> On Tue, 27 Apr 2021, Ryan Joseph via fpc-devel wrote:
>> Continued from our discussion at 
>> https://bugs.freepascal.org/view.php?id=24481.
>>> if the compiler devs will allow me as soon as this is finished I 
>>> want to allow the existing nested functions functionality to work 
>>> with anonymous functions, so at the very least we don't need to 
>>> generate the expensive interface based object which often times is 
>>> not even needed. At that point we would need to make nested 
>>> functions inline-able, which they are currently not. But we're not 
>>> there yet so lets not complicated anything by proposing extensions 
>>> to a feature that doesn't even exist yet.
>> Sven replies:
>>> Getting rid of the interface only works in very narrow circumstances 
>>> that are so seldom in real world code that it is not worth the effort.
>> I'm referring to my test I did a few years ago 
>> (https://github.com/graemeg/freepascal/compare/master...genericptr:anon_funcs) 
>> where I say we can use existing nested functions as a closure when 
>> passing is not required. As you can see I already implemented this 
>> quite easily but it is not related to the new forthcoming closures 
>> feature. I did in fact try to replace the interface with a record on 
>> the old closures branch but I ran into many problems I decided it 
>> wasn't the best route.
>> Indeed there are many times where we don't want a heap allocated 
>> interface you can pass around  but rather a simple inline function 
>> pointer like below. Consider this loop is run 60 times a second and 
>> allocating a useless class every time for no gain. This could easily 
>> be 1000*60=60,000 constructions and allocations of a class.
>>  for i := 0 to entities.Count - 1 do
>>    begin
>>      value := entities[i];
>>      value.SortEntities(function(a, b: TEntity): integer
>>        begin
>>          // do stuff
>>        end
>>      );
>>    end;
>> So anyways what I propose is if a closure is never passed outside of 
>> scope (i.e. temporary) then use anonymous nested functions instead 
>> (like in my GitHub branch). If this is an acceptable approach I will 
>> personally do what is required to get it implemented along side the 
>> real closures.
> Wait.
> I asked Sven to make sure that nested functions are under ALL 
> circumstances
> usable as closures or can be used instead of anonymous functions.
> Pas2js already supports this, and I want FPC and Pas2JS to be 
> compatible in
> this regard.

The compiler will essentially prepare them as if they're anonymous 

> So as Sven wrote, you would be duplicating effort, needlessly, since 
> it has
> to work always... If the compiler can decide that the heap interface 
> is not
> needed and optimize it away: so much the better. But I doubt this will be
> possible.

In nearly all cases the interface can't be optimized away.


More information about the fpc-devel mailing list