Let's get the semantic around closure fixed.

Steven Schveighoffer schveiguy at gmail.com
Wed May 19 18:43:24 UTC 2021


On 5/19/21 1:26 PM, deadalnix wrote:
> On Wednesday, 19 May 2021 at 13:02:59 UTC, Steven Schveighoffer wrote:
>> Thinking about how this would have to be implemented:
>>
>> 1. If you want to access a variable in a scope from both the closure 
>> and the function itself, the variable has to be allocated on the heap.
> 
> This is definitively what D guarantees.

Yes, it is guaranteed... if it compiles. For sure the current behavior 
is junk and unsafe.

> 
>> 2. We need one allocation PER loop. If we do this the way normal 
>> closures are done (i.e. allocate before the scope is entered), this 
>> would be insanely costly for a loop.
> 
> This is costly, but also the only way to ensure other invariants in the 
> language are respected (immutability, no access after destruction, ...).
> 
> This is also consistent with what other languages do.

Again, costly as long as it compiles. If a la Walter's suggestion it no 
longer compiles, then it's moot.

> 
> This is also consistent with the fact that D allow to iterate over loops 
> using opDispatch, which already should exhibit this behavior, because it 
> is a function under the hood.

You mean opApply? Not necessarily, if the delegate parameter is scope 
(and it should be).

> 
>> 3. It *could* allocate on demand. Basically, reserve stack space for 
>> the captured variables, have a pointer to that stack space. When a 
>> closure is used, copy that stack space to a heap allocation, and 
>> switch the pointer to that heap block (so the function itself also 
>> refers to the same data). This might be a reasonable tradeoff. But it 
>> has some limitations -- like if you ever take the address of one of 
>> these variables, that would also have to generate the allocated closure.
>>
> 
> I suspect this will open a can of worm of edge cases.

I don't think a can of worms is opened, but it's not easy to implement 
for sure. I'm not suggesting that we follow this path. I'm just thinking 
about "What's the most performant way we can implement closures used 
inside loops". If a loop *rarely* allocates a closure (i.e. only one 
element actually allocates a closure), then allocating defensively seems 
super-costly.

-Steve


More information about the Digitalmars-d mailing list