On Wednesday, 23 August 2017 at 17:43:27 UTC, Steven
Schveighoffer wrote:
On 8/23/17 11:59 AM, Walter Bright wrote:
On 8/23/2017 7:37 AM, Steven Schveighoffer wrote:
How do dynamic closures work without the GC?
They don't allocate the closure on the GC heap. (Or do I have
static/dynamic closures backwards?)
I thought "closure" means allocating the stack onto the heap so
you can return the delegate with its context intact.
From
https://en.wikipedia.org/wiki/Closure_(computer_programming) :
"A language implementation cannot easily support full closures
if its run-time memory model allocates all automatic variables
on a linear stack. In such languages, a function's automatic
local variables are deallocated when the function returns.
However, a closure requires that the free variables it
references survive the enclosing function's execution.
Therefore, those variables must be allocated so that they
persist until no longer needed, typically via heap allocation,
rather than on the stack, and their lifetime must be managed so
they survive until all closures referencing them have are no
longer in use."
Right, so if we wanted to support closures in betterC (we don't
now, as my earlier example shows), they'd need a separate
lifetime management implementation.
The two straightforward ones are either disable copying of
closures in betterC (only moving them), so a single ownership
model of their heap allocated context pointer is possible
(deallocating the memory once the closure is destroyed), or make
them reference counted.
The first has the disadvantage that you can't have two closures
point to the same heap context (though to be honest, I haven't
seen a codebase so far that actually uses that), but it should be
trivial to implement. The RC variant is more complex (it would
require an analysis if reference cycles can occur), but I think
this might be one of the cases where RC is the right solution
(and we might even consider using RC in normal D as well, if it
works sanely).