www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - rationale for function and delegate

reply "Paulo Pinto" <pjmlp progtools.org> writes:
Hi,

while reading TDPL I start wondering what is the background between function 
and delegate.

They seem to provide more or less the same funcionality, except delegate 
allows the capture
of the function declaration environment.

Most of the programming languages with support for closures only have one 
way of doing it.

Why is D providing two ways of doing it? For me sounds like a feature 
similar to register, or
inline for doing what should be the compilers work. Deciding the best 
implementation for the
closure.

Thanks,
Paulo 
Oct 16 2010
next sibling parent klickverbot <see klickverbot.at> writes:
On 10/16/10 10:40 AM, Paulo Pinto wrote:
 while reading TDPL I start wondering what is the background between function
 and delegate.

delegate() is a function pointer amended with a second context pointer, which allows you to have pointers to member functions, closures and so on. function() is a C-style function pointer and can be used to interface with C code, etc., but obviously not for closures, since it its lacking the context part. There is a clear difference between the two types, Ilthough you probably don't need raw function pointers very often if you are working in a D only environment. If you want to have the compiler decide, you could always use auto…
Oct 16 2010
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday 16 October 2010 01:40:55 Paulo Pinto wrote:
 Hi,
 
 while reading TDPL I start wondering what is the background between
 function and delegate.
 
 They seem to provide more or less the same funcionality, except delegate
 allows the capture
 of the function declaration environment.
 
 Most of the programming languages with support for closures only have one
 way of doing it.
 
 Why is D providing two ways of doing it? For me sounds like a feature
 similar to register, or
 inline for doing what should be the compilers work. Deciding the best
 implementation for the
 closure.
 
 Thanks,
 Paulo

I believe that the two main reasons are 1. function pointers have less overhead. 2. If you want to use function pointers when calling C functions, you need function pointers rather than delegates. but there are probably others. - Jonathan M Davis
Oct 16 2010
next sibling parent "Paulo Pinto" <pjmlp progtools.org> writes:
Ah, ok that makes sense to me.

Although for other languages reason 1 is usually decided by the compiler, 
but then again most
of the modern languages don't interface directly with C.

--
Paulo

"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.641.1287221213.858.digitalmars-d puremagic.com...
 On Saturday 16 October 2010 01:40:55 Paulo Pinto wrote:
 Hi,

 while reading TDPL I start wondering what is the background between
 function and delegate.

 They seem to provide more or less the same funcionality, except delegate
 allows the capture
 of the function declaration environment.

 Most of the programming languages with support for closures only have one
 way of doing it.

 Why is D providing two ways of doing it? For me sounds like a feature
 similar to register, or
 inline for doing what should be the compilers work. Deciding the best
 implementation for the
 closure.

 Thanks,
 Paulo

I believe that the two main reasons are 1. function pointers have less overhead. 2. If you want to use function pointers when calling C functions, you need function pointers rather than delegates. but there are probably others. - Jonathan M Davis

Oct 16 2010
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/16/10 4:26 CDT, Jonathan M Davis wrote:
 On Saturday 16 October 2010 01:40:55 Paulo Pinto wrote:
 Hi,

 while reading TDPL I start wondering what is the background between
 function and delegate.

 They seem to provide more or less the same funcionality, except delegate
 allows the capture
 of the function declaration environment.

 Most of the programming languages with support for closures only have one
 way of doing it.

 Why is D providing two ways of doing it? For me sounds like a feature
 similar to register, or
 inline for doing what should be the compilers work. Deciding the best
 implementation for the
 closure.

 Thanks,
 Paulo

I believe that the two main reasons are 1. function pointers have less overhead. 2. If you want to use function pointers when calling C functions, you need function pointers rather than delegates. but there are probably others.

That's about it. The book mentions 2, whereas 1 is implied. Andrei
Oct 16 2010
prev sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Paulo Pinto (pjmlp progtools.org)'s article
 Hi,
 while reading TDPL I start wondering what is the background between function
 and delegate.
 They seem to provide more or less the same funcionality, except delegate
 allows the capture
 of the function declaration environment.
 Most of the programming languages with support for closures only have one
 way of doing it.
 Why is D providing two ways of doing it? For me sounds like a feature
 similar to register, or
 inline for doing what should be the compilers work. Deciding the best
 implementation for the
 closure.
 Thanks,
 Paulo

Yes, it's ugly but in a systems language you need control over details like whether a context pointer is present in addition to the function pointer. Anyhow, one thing that people always seem to fail to notice is that std.functional has a toDelegate() function that can convert just about any function pointer into a delegate with minimal overhead. This mitigates the situation a lot, since if an API requires a delegate and you have a function pointer, you just do a toDelegate(someFunctionPointer).
Oct 16 2010
next sibling parent reply Juanjo Alvarez <fake fakeemail.com> writes:
On Sat, 16 Oct 2010 14:42:13 +0000 (UTC), dsimcha <dsimcha yahoo.com> 
wrote:
 delegate with minimal overhead.  This mitigates the situation a 

 API requires a delegate and you have a function pointer, you just 

 toDelegate(someFunctionPointer).

Sorry for asking here something that should go to D.learn, but how do you do the reverse, that is, getting a function from a delegate? I need that in my project so I can pass it to signal so some Unix signal will trigger a method of an already instantiated object.
Oct 16 2010
parent reply "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Juanjo Alvarez" <fake fakeemail.com> wrote in message 
news:almarsoft.3733950694952420550 news.digitalmars.com...
 Sorry for asking here something that should go to D.learn, but how do you 
 do the reverse, that is, getting a function from a delegate? I need that 
 in my project so I can pass it to signal so some Unix signal will trigger 
 a method of an already instantiated object.

I wrote some code a while back that lets you forward a windows callback to any delegate. It might be a good starting point for what you want. http://yebblies.com/thunk.d
Oct 17 2010
parent Juanjo Alvarez <fake fakeemail.com> writes:
On Sun, 17 Oct 2010 19:15:48 +1000, "Daniel Murphy" 
<yebblies nospamgmail.com> wrote:
 I wrote some code a while back that lets you forward a windows 

 any delegate.  It might be a good starting point for what you want.

 http://yebblies.com/thunk.d

Thanks genious ;)
Oct 17 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 16 Oct 2010 11:22:43 -0400, Juanjo Alvarez <fake fakeemail.com>  
wrote:

 On Sat, 16 Oct 2010 14:42:13 +0000 (UTC), dsimcha <dsimcha yahoo.com>  
 wrote:
 delegate with minimal overhead.  This mitigates the situation a

 API requires a delegate and you have a function pointer, you just

 toDelegate(someFunctionPointer).

Sorry for asking here something that should go to D.learn, but how do you do the reverse, that is, getting a function from a delegate? I need that in my project so I can pass it to signal so some Unix signal will trigger a method of an already instantiated object.

auto dg = &obj.method; auto fptr = dg.funcptr; auto context = dg.ptr; Note, you cannot call fptr, you will get a runtime error. Here is the related documentation (search for funcptr): http://www.digitalmars.com/d/2.0/function.html I believe there may be in phobos a type which wraps a function pointer into a delegate. Not sure if it was ever added though... -Steve
Oct 16 2010
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 16 Oct 2010 11:57:36 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 On Sat, 16 Oct 2010 11:22:43 -0400, Juanjo Alvarez <fake fakeemail.com>  
 wrote:

 On Sat, 16 Oct 2010 14:42:13 +0000 (UTC), dsimcha <dsimcha yahoo.com>  
 wrote:
 delegate with minimal overhead.  This mitigates the situation a

 API requires a delegate and you have a function pointer, you just

 toDelegate(someFunctionPointer).

Sorry for asking here something that should go to D.learn, but how do you do the reverse, that is, getting a function from a delegate? I need that in my project so I can pass it to signal so some Unix signal will trigger a method of an already instantiated object.

auto dg = &obj.method; auto fptr = dg.funcptr; auto context = dg.ptr; Note, you cannot call fptr, you will get a runtime error. Here is the related documentation (search for funcptr): http://www.digitalmars.com/d/2.0/function.html I believe there may be in phobos a type which wraps a function pointer into a delegate. Not sure if it was ever added though... -Steve

Actually, you can use funcptr for simple functions. Here's an example how: void main(string[] args) { auto foo = (int x){ writeln(x); }; void function(int,void*) bar = foo.funcptr; bar(5,foo.ptr); foo(5); return; } Structs larger than 8 bytes require a hidden return pointer, so instead of LargeStruct function(int,void*) bar; you'd have void function(int,LargeStruct*,void*) bar; However, if Unix code needs to call the function, it needs to do so using the C calling conventions, which are platform/compiler specific.
Oct 16 2010
prev sibling parent Juanjo Alvarez <fake fakeemail.com> writes:
On Sat, 16 Oct 2010 11:57:36 -0400, "Steven Schveighoffer" 
<schveiguy yahoo.com> wrote:
 auto dg = &obj.method;

 auto fptr = dg.funcptr;
 auto context = dg.ptr;

 Note, you cannot call fptr, you will get a runtime error.

Thanks, I'll play with it to see if I can make this work in my code.
Oct 16 2010