www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Delegate/Function Pointers

reply tyro [a.c.edwards] <tyro_member pathlink.com> writes:
Ok...

I get the point that one can use a delegate to refer to a non-static member
function (i.e. as non-static function of a class or struct) and a function
pointer to refer to all other functions (i.e., static members of class and
struct, and non-members). What I don't understand however, is at what point in
more advantageous to use a pointer or a deligate vice a standard function call.

Why would I need to point to a function when I can call it outright? Is there a
time when a delegate or pointer is the only viable means of accomplishing
something? In those cases where a pointer or a deligate is the preferred method:
why would it be so? Is it just a matter of taste?

Thanks in advance,
Andrew
Jan 13 2006
next sibling parent reply Sean Kelly <sean f4.ca> writes:
tyro [a.c.edwards] wrote:
 Ok...
 
 I get the point that one can use a delegate to refer to a non-static member
 function (i.e. as non-static function of a class or struct) and a function
 pointer to refer to all other functions (i.e., static members of class and
 struct, and non-members). What I don't understand however, is at what point in
 more advantageous to use a pointer or a deligate vice a standard function call.
 
 Why would I need to point to a function when I can call it outright? Is there a
 time when a delegate or pointer is the only viable means of accomplishing
 something? In those cases where a pointer or a deligate is the preferred
method:
 why would it be so? Is it just a matter of taste?

I can think of two related scenarios to use function pointers. First, they can be useful when you want to be able to re-use the same piece of code in a number of slightly different ways... particularly if you want the user to be able to specify this. For example: void print( bit delegate( out char ) getChar ) { char c; while( getChar( c ) ) { putchar( c ); } } The delegate passed to the print function above may get its data from a file, from a string, from a socket, etc, but the same print function can be used in each case. The second scenario is that sometimes you just don't know what function you want to execute at design-time. Think of it like polymorphism at the function level. You might have a state machine that spits out different function pointers at different times during its execution, and these pointers may be passed to other functions to perform some operation. Class-level polymorphism can often be used in these cases as well, but if you only ever want to execute a function with a given signature then there's no reason to design a class heirarchy for this purpose--particularly with delegates as they have access to stack data (which makes them a bit like function objects--functors--in C++). Sean
Jan 13 2006
parent reply tyro [a.c.edwards] <tyro_member pathlink.com> writes:
In article <dq8d66$ogg$1 digitaldaemon.com>, Sean Kelly says...
tyro [a.c.edwards] wrote:
 Ok...
 
 I get the point that one can use a delegate to refer to a non-static member
 function (i.e. as non-static function of a class or struct) and a function
 pointer to refer to all other functions (i.e., static members of class and
 struct, and non-members). What I don't understand however, is at what point in
 more advantageous to use a pointer or a deligate vice a standard function call.
 
 Why would I need to point to a function when I can call it outright? Is there a
 time when a delegate or pointer is the only viable means of accomplishing
 something? In those cases where a pointer or a deligate is the preferred
method:
 why would it be so? Is it just a matter of taste?

I can think of two related scenarios to use function pointers. First, they can be useful when you want to be able to re-use the same piece of code in a number of slightly different ways... particularly if you want the user to be able to specify this. For example: void print( bit delegate( out char ) getChar ) { char c; while( getChar( c ) ) { putchar( c ); } }

So in this regard I don't have to know the actual name of the function being called prior to implementing my own?
The delegate passed to the print function above may get its data from a 
file, from a string, from a socket, etc, but the same print function can 
be used in each case.

but I could achieve the same from a direct function call and still not know it's implementation: # void main() # { # print(); # } # # static char[] str="Test"; # # bit getChar(out char c) # { # if(str.length > 0) # { # c = str[0]; # str = str[1 .. $]; # return true; # } # return false; # } # # void print() # { # char c; # while( getChar( c ) ) # { # writef( c ); # } # } as long as the function I call modifies a char argument and returns a bit the result is the same. So what, other than the fact with the pointer I don't know the function name beforehand, makes the use of the pointer that much better?
The second scenario is that sometimes you just don't know what function 
you want to execute at design-time.  Think of it like polymorphism at 
the function level.  You might have a state machine that spits out 
different function pointers at different times during its execution, and 
these pointers may be passed to other functions to perform some 
operation.  Class-level polymorphism can often be used in these cases as 
well, but if you only ever want to execute a function with a given 
signature then there's no reason to design a class heirarchy for this 
purpose--particularly with delegates as they have access to stack data 
(which makes them a bit like function objects--functors--in C++).

Ok... this I can understand. Still having a dificulty grasping the first scenario though. Not that I don't understand what it does. Just why it would be necessary.
Sean

Jan 13 2006
next sibling parent David Medlock <noone nowhere.com> writes:
tyro [a.c.edwards] wrote:
 In article <dq8d66$ogg$1 digitaldaemon.com>, Sean Kelly says...
 
tyro [a.c.edwards] wrote:

Ok...

I get the point that one can use a delegate to refer to a non-static member
function (i.e. as non-static function of a class or struct) and a function
pointer to refer to all other functions (i.e., static members of class and
struct, and non-members). What I don't understand however, is at what point in
more advantageous to use a pointer or a deligate vice a standard function call.

Why would I need to point to a function when I can call it outright? Is there a
time when a delegate or pointer is the only viable means of accomplishing
something? In those cases where a pointer or a deligate is the preferred method:
why would it be so? Is it just a matter of taste?

I can think of two related scenarios to use function pointers. First, they can be useful when you want to be able to re-use the same piece of code in a number of slightly different ways... particularly if you want the user to be able to specify this. For example: void print( bit delegate( out char ) getChar ) { char c; while( getChar( c ) ) { putchar( c ); } }

So in this regard I don't have to know the actual name of the function being called prior to implementing my own?
The delegate passed to the print function above may get its data from a 
file, from a string, from a socket, etc, but the same print function can 
be used in each case.

but I could achieve the same from a direct function call and still not know it's implementation: # void main() # { # print(); # } # # static char[] str="Test"; # # bit getChar(out char c) # { # if(str.length > 0) # { # c = str[0]; # str = str[1 .. $]; # return true; # } # return false; # } # # void print() # { # char c; # while( getChar( c ) ) # { # writef( c ); # } # } as long as the function I call modifies a char argument and returns a bit the result is the same. So what, other than the fact with the pointer I don't know the function name beforehand, makes the use of the pointer that much better?
The second scenario is that sometimes you just don't know what function 
you want to execute at design-time.  Think of it like polymorphism at 
the function level.  You might have a state machine that spits out 
different function pointers at different times during its execution, and 
these pointers may be passed to other functions to perform some 
operation.  Class-level polymorphism can often be used in these cases as 
well, but if you only ever want to execute a function with a given 
signature then there's no reason to design a class heirarchy for this 
purpose--particularly with delegates as they have access to stack data 
(which makes them a bit like function objects--functors--in C++).

Ok... this I can understand. Still having a dificulty grasping the first scenario though. Not that I don't understand what it does. Just why it would be necessary.
Sean


allow second order recursion: http://www.latrobe.edu.au/philosophy/phimvt/s00bok.html (begin around Chapter 7 or 8, its heady stuff but very cool) -DavidM
Jan 13 2006
prev sibling parent Sean Kelly <sean f4.ca> writes:
tyro [a.c.edwards] wrote:
 In article <dq8d66$ogg$1 digitaldaemon.com>, Sean Kelly says...
 tyro [a.c.edwards] wrote:
 Ok...

 I get the point that one can use a delegate to refer to a non-static member
 function (i.e. as non-static function of a class or struct) and a function
 pointer to refer to all other functions (i.e., static members of class and
 struct, and non-members). What I don't understand however, is at what point in
 more advantageous to use a pointer or a deligate vice a standard function call.

 Why would I need to point to a function when I can call it outright? Is there a
 time when a delegate or pointer is the only viable means of accomplishing
 something? In those cases where a pointer or a deligate is the preferred
method:
 why would it be so? Is it just a matter of taste?

they can be useful when you want to be able to re-use the same piece of code in a number of slightly different ways... particularly if you want the user to be able to specify this. For example: void print( bit delegate( out char ) getChar ) { char c; while( getChar( c ) ) { putchar( c ); } }

So in this regard I don't have to know the actual name of the function being called prior to implementing my own?
 The delegate passed to the print function above may get its data from a 
 file, from a string, from a socket, etc, but the same print function can 
 be used in each case.

but I could achieve the same from a direct function call and still not know it's implementation: # void main() # { # print(); # } # # static char[] str="Test"; # # bit getChar(out char c) # { # if(str.length > 0) # { # c = str[0]; # str = str[1 .. $]; # return true; # } # return false; # } # # void print() # { # char c; # while( getChar( c ) ) # { # writef( c ); # } # } as long as the function I call modifies a char argument and returns a bit the result is the same. So what, other than the fact with the pointer I don't know the function name beforehand, makes the use of the pointer that much better?
 The second scenario is that sometimes you just don't know what function 
 you want to execute at design-time.  Think of it like polymorphism at 
 the function level.  You might have a state machine that spits out 
 different function pointers at different times during its execution, and 
 these pointers may be passed to other functions to perform some 
 operation.  Class-level polymorphism can often be used in these cases as 
 well, but if you only ever want to execute a function with a given 
 signature then there's no reason to design a class heirarchy for this 
 purpose--particularly with delegates as they have access to stack data 
 (which makes them a bit like function objects--functors--in C++).

Ok... this I can understand. Still having a dificulty grasping the first scenario though. Not that I don't understand what it does. Just why it would be necessary.

For a more complex example, look at my readf implementation available here: http://www.home.f4.ca/sean/d/ (It's the "stdio addon - includes unformat and readf" link) Basically, I pass different getChar delegates to the low-level implementation so I can use the same parser regardless of the input source. Other designs are obviously possible, but this one seemed the most straightforward at the time. Sean
Jan 13 2006
prev sibling next sibling parent Lars Ivar Igesund <larsivar igesund.net> writes:
tyro [a.c.edwards] wrote:

 Ok...
 
 I get the point that one can use a delegate to refer to a non-static
 member function (i.e. as non-static function of a class or struct) and a
 function pointer to refer to all other functions (i.e., static members of
 class and struct, and non-members). What I don't understand however, is at
 what point in more advantageous to use a pointer or a deligate vice a
 standard function call.
 
 Why would I need to point to a function when I can call it outright? Is
 there a time when a delegate or pointer is the only viable means of
 accomplishing something? In those cases where a pointer or a deligate is
 the preferred method: why would it be so? Is it just a matter of taste?
 
 Thanks in advance,
 Andrew

The callback pattern is quite common in libraries were you want to provide the application an easy way to handle events. The application can register a function pointer/delegate with the library for a given event. When that event happens, for example a user clicks on some part of the GUI, the registered function is fired, doing something funky in the application, maybe saving a document or something entirely different. Lars Ivar Igesund
Jan 13 2006
prev sibling parent "Kris" <fu bar.com> writes:
the standard C "function-pointer" permits a level of indirection that can be 
useful for certain types and styles of programming.

The D 'function' is identical to a C function-pointer, while the D 
'delegate' goes one further: it permits a developer to associate arbitrary 
"state" with the traditional C function-pointer (the class or struct 
attributes associated with the delegate function itself).

Thus they are both a means of indirection (or function level polymorphism, 
as Sean noted).


"tyro [a.c.edwards]" <tyro_member pathlink.com> wrote in message 
news:dq8bqm$n75$1 digitaldaemon.com...
 Ok...

 I get the point that one can use a delegate to refer to a non-static 
 member
 function (i.e. as non-static function of a class or struct) and a function
 pointer to refer to all other functions (i.e., static members of class and
 struct, and non-members). What I don't understand however, is at what 
 point in
 more advantageous to use a pointer or a deligate vice a standard function 
 call.

 Why would I need to point to a function when I can call it outright? Is 
 there a
 time when a delegate or pointer is the only viable means of accomplishing
 something? In those cases where a pointer or a deligate is the preferred 
 method:
 why would it be so? Is it just a matter of taste?

 Thanks in advance,
 Andrew

 

Jan 13 2006