www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to know whether to use function or delegate

reply Reiner Pope <reiner.pope gmail.com> writes:
When making a program with a callback, how do you decide whether to use 
a function or a delegate? E.g,

   void foo(void function(int) consume)
   { ... }

or

   void foo(void delegate(int) consume)
   { ... }
Jul 16 2006
next sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Reiner Pope wrote:
 When making a program with a callback, how do you decide whether to use 
 a function or a delegate? E.g,
 
   void foo(void function(int) consume)
   { ... }
 
 or
 
   void foo(void delegate(int) consume)
   { ... }

Delegates are functions with context. They are therefore more useful in the general case. (It is easier to turn a function into a delegate than vice-versa.) However, which one you want depends on your use-case. When in doubt, I would default to using a delegate. This allows the use of lambda functions as callbacks, if nothing else. Walter has said on a number of occasions that he eventually (as in, 2.0) wants to make function pointers and delegates the same thing, which will make the question moot. -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wiki
Jul 17 2006
parent reply Reiner Pope <reiner.pope gmail.com> writes:
Kirk McDonald wrote:
 Reiner Pope wrote:
 When making a program with a callback, how do you decide whether to 
 use a function or a delegate? E.g,

   void foo(void function(int) consume)
   { ... }

 or

   void foo(void delegate(int) consume)
   { ... }

Delegates are functions with context. They are therefore more useful in the general case. (It is easier to turn a function into a delegate than vice-versa.) However, which one you want depends on your use-case. When in doubt, I would default to using a delegate. This allows the use of lambda functions as callbacks, if nothing else. Walter has said on a number of occasions that he eventually (as in, 2.0) wants to make function pointers and delegates the same thing, which will make the question moot.

Thanks for the response. I thought that was the case, but I didn't really see why functions would really be in the spec in that case.
Jul 17 2006
parent Lionello Lunesu <lio lunesu.remove.com> writes:
Reiner Pope wrote:
 Thanks for the response. I thought that was the case, but I didn't 
 really see why functions would really be in the spec in that case.

For extern (C) functions that only want a function pointer, like qsort's int (*compare)(void*,void*) L. Notice that you can easily wrap a function to pass it as a delegate, using the new function literal syntax. There's another post in this group explaining it in more detail.
Jul 18 2006
prev sibling next sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Reiner Pope wrote:
 When making a program with a callback, how do you decide whether to use 
 a function or a delegate? E.g,
 
   void foo(void function(int) consume)
   { ... }
 
 or
 
   void foo(void delegate(int) consume)
   { ... }

I would say, when in doubt, go with delegate. Why? Consider usage examples of your foo()'s signature: Example #1 - Using it with an established delegate, say bar() of some instance: # foo(&obj.bar); Simple! If you made it a function pointer, then (as far as I know) using member functions and nested functions (which would be done the same way as above, just without 'obj') ceases to be possible at all. (If there is a hack or workaround to pass a delegate as a function pointer, I want to see that!) Example #2 - Using an anonymous delegate: # foo((int a){ # /*do stuff*/ # }); Concise! The utility of this should be fairly self-explanatory. Example #3 - You can still use it with a function, by wrapping it in an anonymous delegate: # void bar (int a) { # /*do stuff*/ # } # # foo((int a) { # bar(a); # }); Intuitive? Maybe not; but still quite straight-forward. -- Chris Nicholson-Sauls
Jul 17 2006
next sibling parent reply Reiner Pope <reiner.pope gmail.com> writes:
 Example #3 - You can still use it with a function, by wrapping it in an 
 anonymous delegate:
 # void bar (int a) {
 #   /*do stuff*/
 # }
 #
 # foo((int a) {
 #   bar(a);
 # });

do it.
Jul 17 2006
parent Don Clugston <dac nospam.com.au> writes:
Reiner Pope wrote:
 Example #3 - You can still use it with a function, by wrapping it in 
 an anonymous delegate:
 # void bar (int a) {
 #   /*do stuff*/
 # }
 #
 # foo((int a) {
 #   bar(a);
 # });

do it.

The calling convention is actually different, you need to create a 'thunk' to convert function to delegate. The compiler doesn't do this for you yet.
Jul 17 2006
prev sibling parent Walter Bright <newshound digitalmars.com> writes:
Chris Nicholson-Sauls wrote:
 (If there is a hack or workaround to pass a delegate as a function 
 pointer, I want to see that!)

The only way to do it is to generate a "thunk" of executable code at runtime.
Jul 22 2006
prev sibling parent Chad J <gamerChad _spamIsBad_gmail.com> writes:
Reiner Pope wrote:
 When making a program with a callback, how do you decide whether to use 
 a function or a delegate? E.g,
 
   void foo(void function(int) consume)
   { ... }
 
 or
 
   void foo(void delegate(int) consume)
   { ... }

I started a thread along these lines not too long ago, and it had some good responses. Here it is: digitalmars.D.learn/3700
Jul 17 2006