confusing (buggy?) closure behaviour

Zoran Isailovski dmd.zoc at spamgourmet.com
Sat Dec 13 03:59:51 PST 2008


Sergey Gromov Wrote:

> Fri, 12 Dec 2008 15:24:39 -0500, Zoran Isailovski wrote:
> 
> > Denis Koroskin Wrote:
> > 
> >>>> On Fri, 12 Dec 2008 19:32:03 +0300, Zoran Isailovski
> >>>> <dmd.zoc at spamgourmet.com> wrote:
> >>>>
> >>>> > I'm an experienced C#, Java and Python programmer, and have employed
> >>>> > closures (and C# delegates) upon numerous occasions. While  
> >>>> experimenting
> >>>> > with D closures and delegates, I was stroke by a phenomenon I cannot
> >>>> > explain. Here's the code:
> >> As a rule of thumb, you shoudn't don't return local delegate from a  
> >> function in D1, but you may safely pass them down the call stack.
> > 
> > I don't think it is restrictive if the compiler prevented a situation
> > that would otherwise lead to a run-time error anyway, or worse, weird
> > and confusing run-time behavior. In my case, if the compiler couldn't
> > SAFELY handle a reference to the argument n outside the enclosing
> > function, then, IMO, RETURNING it (but not otherwise using it) should
> > be flagged a compilation error. Admittedly, detecting this is a bit
> > more involved for the compiler, but not at all restrictive for the
> > user.
> 
> There are situations where proving that n escapes the function is hard
> and requires extensive flow analysis.  It may be impossible to prove
> when one module of a large program is compiled separately.  And it may
> be impossible to prove for library code where user code is unknown by
> definition. Therefore the decision is left to the programmer.  This is
> indeed unsafe, and D2 tries to solve this by introducing full,
> heap-allocated closures.  This in turn brings performance problems in
> situations where stack closures would be sufficient.  Now significant
> effort is made towards allowing stack closures in D2 where it would be
> safe.

Sergey,  thanks for taking the time to respond.

I think you are talking about allowing all usages that may be potentially safe. I was talking about disallowing all usages  that may be potentially unsafe. (This was indeed one of the main differences in "philosophy" between languages in the C family, and languages in the ALGOL family. I truly hope D will be coming closer to the latter.)

Anyway, following the latter pattern, you don't need global analysis. You can determine if n is on the stack (it is - it's an argument), you can determine if it's referenced from within the closure (it is), and you can determine if the closure is being returned (it is). The compiler should IMO then generate an error (or warning) about the return statement, perhaps stating something like "cannot return a delegate that refers to variables in local scope", or something like that.

> That said, the full closure feature won't make its way into D1.  D1
> closures will stay as they are.

I see. And I'd love to switch to D2, but I just can't get DFL working with it (on Win32).


More information about the Digitalmars-d-learn mailing list