[fpc-devel] Delphi anonymous methods

Sven Barth pascaldragon at googlemail.com
Sat Mar 2 23:22:17 CET 2013


On 02.03.2013 20:55, Sven Barth wrote:
>> Also there are open questions which require brainstorm:
>> 1. Does Pascal needs other implementation of closures which is different
>> from anonymous methods implementation?
>
> I would say no. After all the method implementation itself stays the
> same, but the captured variables should be different. Or what does this
> print:

I've now read through your PDF and somehow I'd like to have a better 
implementation in FPC. Let's consider the following code (Note: I've 
never used anonymous methods yet, so this is what I naively would expect):

=== code begin ===

var
   i: LongInt;
   SomeProc1, SomeProc2: reference to procedure;
begin
   i := 42;

   SomeProc1 := procedure
                begin
                  Writeln('Proc1: ' + i);
                end;

   i := 21;

   SomeProc2 := procedure
                begin
                  Writeln('Proc2: ' + i);
                end;

   SomeProc1;
   SomeProc2;
end;

=== code end ===

The output I'd expect here is the following:

=== output begin ===

42
21

=== output end ===

But if I've understood you correctly I'll get the following instead:

=== output begin ===

21
21

=== output end ===

I don't like this -.-

You also wrote that local variables seem to be located on the 
FrameObject. So how is it with multi threading? E.g.

=== example begin ===

for i := 0 to 5 do
   TThread.CreateAnonymousThread(
     procedure
     var
       x: LongInt;
     begin
       x := Random;
       Writeln('Before ', TThread.CurrentThread.ThreadID, ': ', x);
       Sleep(x);
       Writeln('After ', TThread.CurrentThread.ThreadID, ': ', x);
     end).Start;

=== example end ===

If the "x" is really located in the FrameObject and that object exists 
only once then it is rather likely that the output of 'Before 123: ' is 
different from the output of 'After 123: ', right? Again I think this is 
a bad thing...

So in my opinion an implementation with a stricter division between the 
single instances of an anonymous function would be the better choice. 
Also local variables should reside on the stack of the anonymous 
function... as we generate the code of nested procedures/functions only 
after the complete outer function was parsed (and AFAIK also had its 
code generated) we should be able to "easily" add the generation of 
anonymous function bodies as well. So we should have multiple smaller 
objects storage objects that only contain those variables of the outer 
function and those nested functions that are really used instead of one 
big FrameObject. It might be quite a bit harder to implement in a 
correct and good (and maybe also performant) way, but we would - at 
least in my opinion - gain a more logical and straight implementation of 
closures.

Regards,
Sven



More information about the fpc-devel mailing list