Let's get the semantic around closure fixed.

deadalnix deadalnix at gmail.com
Wed May 19 07:36:32 UTC 2021


On Wednesday, 19 May 2021 at 03:09:03 UTC, Walter Bright wrote:
> The general rule for determining "what should happen here" when 
> there are abstractions around pointers (such as arrays, 
> delegates, refs, outs, class references, etc.), is to rewrite 
> it in explicit terms of those pointers. The (sometimes 
> baffling) behavior is then exposed for what it actually is, and 
> the behavior should match.
>

No, this is definitively wrong.

Languages constructs provide invariant, that both the developers 
and the compiler can rely on. These invariant ensure that the 
codebase can scale to larger size while keeping bugs, complexity, 
extensibility and so on in check.

It is capital to look at language constructs through that lens, 
or, very quickly, one end up with sets of invariant that vanish 
to nothing because they are not provided consistently by various 
languages constructs.

This results in more complexity for the programmer, more bugs, 
and slower programs because the runtime and compiler cannot 
leverage the invariant either.

Thinking through the way it is all implemented with pointer is 
definitively useful too, but simply as a tool to know what can be 
implemented efficiently and what cannot, what can be optimized 
easily and what cannot, etc... This is not very useful as a 
design tool, as it lads to unsound language constructs.

In fact, not even C++ works this way, as they went through great 
length to define a virtual machine that does not exist that would 
execute the C++ in their spec.

> Granted, there is a special kludge in the compiler to sometimes 
> put the variables referenced by the delegate into a closure 
> allocated by the gc, but that doesn't account for variables 
> that go out of scope before the function scope ends. There is 
> no process to make a closure for them, and adding such a 
> capability is likely much more complication than added value, 
> and so should just be an error.

I find it surprising that you call this a kludge. This is how 
pretty much any language except C++ does it. It is proven. 
Without this and without the ability to capture by value like in 
C++, delegates are effectively useless.

This is not a kludge, this is the very thing that makes delegates 
useful at all.

That being said, the DIP1000 analysis you mention is a useful 
tool here. If nothing escape, then it is possible for the 
compiler to promote the closure on stack rather than on heap.

This is where attacking the problem from first principles helps. 
It is not about the pointers, it is about the invariants. If the 
compiler can find a better way to implement these invariants 
given a set of conditions, then great.



More information about the Digitalmars-d mailing list