Idea: "Frozen" inner function

Michael Butscher mbutscher at gmx.de
Sun Nov 26 06:19:59 PST 2006


Jarrett Billingsley wrote:
> "Michael Butscher" <mbutscher at gmx.de> wrote in message 
> news:MPG.1fd2668cdc5c74998969d at news.digitalmars.com...
> 
> > The only efficiency tradeoff of frozen functions is the copying at the
> > time of definition (and later the freeing of the context memory).
> > Except for that they would be as efficient as inner functions.
> 
> If in a loop, or in a function which is called a lot, that would be a lot of 
> allocations, which is particularly wasteful if you never return the closure 
> from the function.

It is up to the programmer to place the definition of the "closure" at 
a point where it is only executed if needed, e.g. it could be placed 
directly before it is returned by the outer function. The allocation of 
the heap could be executed only when reaching the definition of the 
frozen function.

My example might have been a bit misleading.


>  I'd say a very large percentage of the time, you don't 
> need to return nested functions, so it'd be wasteful to enable the feature 
> when it's not used that often.

One field of application would also be to create small event handlers 
for GUI events. This happens more often, I think.

But maybe it is really not needed so often, but I remember that there 
were already some discussions about closures, so I wanted to propose 
this simpler alternative.


> Additionally, there's the problem of functions with several levels of 
> nesting.  If you have c() inside b() inside a(), if c() accesses local 
> variables of both b() and a(), when b() returns (but still inside a()), the 
> closure of c() will have to be able to access the active locals of a() on 
> the stack, but the locals of b() will have to be on the heap.

If c() would be defined frozen, it just has all variables declared in c
() itself on the stack and all variables declared somewhere outside on 
the heap (as a copy). It does especially NOT access the active locals 
of a(), but the locals as they were when c() was defined.

If the original outside-variables exist on the stack yet is totally 
irrelevant.


>  This would 
> have to be done through some second level of indirection or using multiple 
> context pointers.  This problem exists in languages such as Lua (and mine, 
> MiniD!) and is handled with tricky things called upvalues, which are a 
> second level of indirection for each outer function local.  I don't know how 
> well something like that would fit into a lower-level language like D.

Therefore my proposal is much simpler to realize than that.


> > This would be technically the same, but, as you wrote, less convenient.
> 
> For the time being, though, it's certainly a nice (and simple) alternative / 
> workaround.  It also has the advantage that you can very selectively control 
> if/when the closure's context is allocated on the heap.

But I also have to remember which outer variables are accessed. If I 
change the code of the inner function I could forget to copy a variable 
or copy unnecessary variables.

My idea is not new but just more convenient and less error prone than 
the anonymous class technique.



Michael



More information about the Digitalmars-d mailing list