Full closures

Frank Benoit keinfarbton at googlemail.com
Mon Aug 18 09:21:24 PDT 2008


Bruno Medeiros schrieb:
> Frank Benoit wrote:
>> Like shown in http://d.puremagic.com/issues/show_bug.cgi?id=2043
>> i think the current full closure implementation should take a redesign.
>>
>> My suggestion:
>> Let D have 2 kind of delegate closures (I don't know how to call this 
>> correctly)
>> local delegates and heap delegates
>>
>> local delegate are that from D1 without modifiction.
>> They can access every local variable in the surrounding scope, no heap 
>> allocation if the addess is taken. It is expected the adress is not 
>> used outside the allowed scope.
>>
> 
> Refresh my memory on why would that be wanted. Is it because the 
> compiler incorrectly heap allocates some variables in a situation that 
> is statically verifiable that such allocation wasn't necessary?
> Or is it more of a programmer's help, to avoid him/her making mistakes 
> and writing code that inadvertently causes locals to be heap allocated?
> 

the D1 nested functions or anonymous classes can access local variable 
from the surrounding scope. local vars are located on the stack. if the 
reference to the nested function of anonymous class is escaping the 
local scope (by storing it somewhere or passing it or returning it) and 
the surrounding scope if left, the variables are no more valid. Running 
the nested function or anonymous class accessing those variable will 
result in crashes.

So the D1 feature is very good in performance, but it should be taken 
care or the livetime of the accessed variables.

The D2 "full closure" feature allocated the whole stack frame on the 
stack, if the compile detects the "take address from nested function".

> 
>> heap delegates
>> - can only access variables from the surrounding scope, if they are 
>> marked as 'const', 'invariant' or 'final'. Which means, they are not 
>> expected to changed after initialization.
>> - with instantiation of the delegate, a heap allocated frame is used 
>> to store a copy of the reference 'final' varialbles for the delegate.
>> That means in case of a loop, the delegate get a new heap allocation 
>> with each iteration.
>>
>> foreach( element; container ){
>>   const c = element;
>>   logLater( new { writefln(c); });
>> }
>>
>>
> 
> Why would we want such version of "heap delegates" that are more 
> restrictive in power than D's current full closures?
> 

The current D2 approach of simply allocating the whole stack frame looks 
good on the first sight, but IMHO it is not sufficient.
- it breaks the old semantic
- it always do heap allocation, but the old semantic is an important D 
feature.
- it make invariant/const data change value, if used in a loop.

See the link to the bug report.

This is why i think, for the case of "heap delegates" the access should 
be restricted to constant data, and that data should be copied to the 
delegate, instead of heap-ing the surrounding scope stack frame.





More information about the Digitalmars-d mailing list