Thread overview
delegate vs function
Nov 23, 2010
spir
Nov 23, 2010
spir
November 23, 2010
Hello,

alias void function (int) F;
alias void delegate (int) D;

void fnFunc (F f, int i) {f(i);}
void dgFunc (D d, int i) {d(i);}

void writeOut (int i) {writeln(i);}

void test () {
    void writeIn (int i) {writeln(i);}
    fnFunc(&writeOut, 1);
    dgFunc(&writeIn, 1);
//~     fnFunc(&writeIn, 1);    // error (expected a func, got a delegate...)
//~     dgFunc(&writeOut, 1);   // error (... and conversely)
}

If a function is defined at the module's toplevel and then passed (via a pointer) to a higher-order func that expects a function, al works fine. But if it is defined inside a function, then the pointer is automatically typed as delegate, even if the function does not use any variable in scope, and I get an error. Conversely, if the higher order func is defined to expect a delegate, then it fails if I pass a func defined at the top-level.
How to solve this?


Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

November 23, 2010
On Tue, 23 Nov 2010 13:15:46 +0100, spir wrote:

> Hello,
> 
> alias void function (int) F;
> alias void delegate (int) D;
> 
> void fnFunc (F f, int i) {f(i);}
> void dgFunc (D d, int i) {d(i);}
> 
> void writeOut (int i) {writeln(i);}
> 
> void test () {
>     void writeIn (int i) {writeln(i);}
>     fnFunc(&writeOut, 1);
>     dgFunc(&writeIn, 1);
> //~     fnFunc(&writeIn, 1);    // error (expected a func, got a
> delegate...) //~     dgFunc(&writeOut, 1);   // error (... and
> conversely) }
> 
> If a function is defined at the module's toplevel and then passed (via a pointer) to a higher-order func that expects a function, al works fine. But if it is defined inside a function, then the pointer is automatically typed as delegate, even if the function does not use any variable in scope, and I get an error.

Mark the function as 'static', like this:

  static void writeIn(int i) { ... }

Then the compiler even ensures that it doesn't use any symbols from the enclosing scope.


> Conversely, if the higher order
> func is defined to expect a delegate, then it fails if I pass a func
> defined at the top-level. How to solve this?

Use std.functional.toDelegate(), like this:

  dgFunc(toDelegate(&writeOut), 1);

(For some reason the documentation for toDelegate() seems to be missing from the D web site, but I don't know why.  I'll look into it.)

-Lars
November 23, 2010
On Tue, 23 Nov 2010 12:25:18 +0000, Lars T. Kyllingstad wrote:

> (For some reason the documentation for toDelegate() seems to be missing
> from the D web site, but I don't know why.  I'll look into it.)

Ah, found it: http://d.puremagic.com/issues/show_bug.cgi?id=2581

-Lars
November 23, 2010
On Tue, 23 Nov 2010 12:25:18 +0000 (UTC)
"Lars T. Kyllingstad" <public@kyllingen.NOSPAMnet> wrote:

> On Tue, 23 Nov 2010 13:15:46 +0100, spir wrote:
> 
> > Hello,
> > 
> > alias void function (int) F;
> > alias void delegate (int) D;
> > 
> > void fnFunc (F f, int i) {f(i);}
> > void dgFunc (D d, int i) {d(i);}
> > 
> > void writeOut (int i) {writeln(i);}
> > 
> > void test () {
> >     void writeIn (int i) {writeln(i);}
> >     fnFunc(&writeOut, 1);
> >     dgFunc(&writeIn, 1);
> > //~     fnFunc(&writeIn, 1);    // error (expected a func, got a
> > delegate...) //~     dgFunc(&writeOut, 1);   // error (... and
> > conversely) }
> > 
> > If a function is defined at the module's toplevel and then passed (via a pointer) to a higher-order func that expects a function, al works fine. But if it is defined inside a function, then the pointer is automatically typed as delegate, even if the function does not use any variable in scope, and I get an error.
> 
> Mark the function as 'static', like this:
> 
>   static void writeIn(int i) { ... }
> 
> Then the compiler even ensures that it doesn't use any symbols from the enclosing scope.

Great! that is what I have missed.

> > Conversely, if the higher order
> > func is defined to expect a delegate, then it fails if I pass a func
> > defined at the top-level. How to solve this?
> 
> Use std.functional.toDelegate(), like this:
> 
>   dgFunc(toDelegate(&writeOut), 1);

All right; if I understand, toDelegate cast a pointer to func to a delegate (the pair of pointers)? (Avoiding the error.) I would enjoy this cast to be automatic. So that, if we know original funcs may be of either kind, we can quietly declare the parameter type as delegate.

> (For some reason the documentation for toDelegate() seems to be missing from the D web site, but I don't know why.  I'll look into it.)
> 
> -Lars




-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com