Thread overview
How to know whether to use function or delegate
Jul 17, 2006
Reiner Pope
Jul 17, 2006
Kirk McDonald
Jul 17, 2006
Reiner Pope
Jul 18, 2006
Lionello Lunesu
Jul 17, 2006
Reiner Pope
Jul 17, 2006
Don Clugston
Jul 22, 2006
Walter Bright
Jul 17, 2006
Chad J
July 17, 2006
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)
  { ... }
July 17, 2006
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
July 17, 2006
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
July 17, 2006
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.
July 17, 2006
> 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);
> # });
Is it really necessary to *wrap* it? I'm surprised there isn't a cast to do it.
July 17, 2006
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);
>> # });
> Is it really necessary to *wrap* it? I'm surprised there isn't a cast to 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.
July 17, 2006
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:
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.learn/3700
July 18, 2006
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.
July 22, 2006
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.