Dynamic closure vs static closure

Yigal Chripun yigal100 at gmail.com
Sat Oct 25 06:30:30 PDT 2008


I probably don't understand something here, but why does the delegate
itself need to know anything about allocation?

see my comments in the body of your message.

KennyTM~ wrote:
> 
> OK. Then both the call site and the function need the "scope", since the
> function signature alone is surely insufficient to determine if the
> delegate is closure or not.
> 
> Since filling the parameter is just a cloning process, this can be
> reduced to asking if
> 
>    <delegate-type> f = g;
> 
> will produce something weird, when one side is a closure, etc.
> 
> The simple solution is to make the delegates on stack a super type of
> delegates on heap.
> 
> (Don't mind the "static" keyword yet. I followed the name "static
> closure" described somewhere else. I agree "static" is too overloaded.)
> 
> 
> 
> --------
> 
> alias float delegate(in float) FloatDelegate;
> 
> // by default delegates are on heap for access safety.
> FloatDelegate g, sin_pi;
> 
> // but I can declare it only needs to live on stack.
> // i.e. the parameters won't jump out of its scope.
> static(FloatDelegate) h;

change the above to:

scope FloatDelegate h; // note: *same* type for dg

> 
> // require allocation on heap. (right? right?)
> void store (FloatDelegate f) {
>   .g = f;
> }
> 
the above will heap allocate.

> // don't require to allocation on heap
> float evaluate_at (static(FloatDelegate) f, in float x) {
>   return f(x);
> }

float evaluate_at (FloatDelegate f, in float x) {
   return f(x);
}


> 
> // don't just deal with parameters... the return values need to be
> considered as well.
> FloatDelegate square (FloatDelegate f) {
>   return float delegate(in float x) { return f(x)*f(x); }
> }

ok. you'll get heap alloc.

> FloatDelegate plus_zero_of (static(FloatDelegate) f) {
>   auto at_zero = f(0);
>   return float delegate(in float x) { return x + at_zero; };
> }

FloatDelegate plus_zero_of (scope FloatDelegate f) {
   auto at_zero = f(0);
   return float delegate(in float x) { return x + at_zero; };
}

> static(FloatDelegate) get_zero_function () {
>   return static float delegate(in float) { return 0; };
> }

the above seems wrong to me. it's the same as returning scope class
instances..just define:
FloatDelegate get_zero_function () {
   return float delegate(in float) { return 0; };
}

and use:
scope dg1 = get_zero_function(); // this'll prevent heap alloc

> 
> 
> {
>   float pi = 3.1415926535f;
>   // don't require allocation on heap.
>   // I know this, therefore the static in front.
>   auto cos_pi = static float delegate(in float y){ return cos(pi * y); };
>   auto tan_pi = static float delegate(in float y){ return tan(pi * y); };

rewrite as:
 auto cos_pi = scope float delegate(in float y){ return cos(pi * y); };
 auto tan_pi = scope float delegate(in float y){ return tan(pi * y); };

> 
>   // delegate on stack set to another delegate on stack: OK.
>   writefln(evaluate_at(tan_pi, 0.2f));

doesn't matter what "kind" of delegate tan_pi is.
> 
>   // require allocation on heap
>   sin_pi = float delegate(float y) { return sin(pi * y); }
> 
>   // Oops, cos_pi is on stack, but the func sig requires on heap.
>   // should generate error.
>   //store(cos_pi);

either error because you assign a scope object to non-scope or perhaps
better alternatives:
a. you use:
store(cos_pi.dup); // manually alloc on heap
b. not an error. *compiler* automatically allocates a copy on heap.

> }
> 
> // sin_pi already on heap, although the func sig said can be on stack.
> // should _not_ generate error.
> writefln(evaluate_at(sin_pi, 0.4f));
> 
> // g can now stay on stack, although its type is a closure.
> g = get_zero_function();
> 
> // also ok.
> h = get_zero_function();
> 
> // this should fail.
> h = g;

anyway, I think you got my intention by now.
I really don't want to have 3 kinds of function types. I think the
already exsisting separation between function pointers and delegates
could be handled better by adding an implicit cast.





More information about the Digitalmars-d mailing list