www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Newbie initial comments on D language - delegate

reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
As I was reading about delegates and the syntax to initialize them I was
thinking that such similar natural syntax had been suggested to C++ many
times over the years. Of course delegates already have their antecedents
in C++ Builder closures and .Net delegates among others. My reaction to
delegates and their elegant syntax was "bravo, of course" but I also had
the reaction of why are there both 'delegate' and 'function'.

Later in the pdf documentation I saw the a note that the future might
see 'delegate' and 'function' folded into a single callable type. My
reaction to this is: ABSOLUTELY NECESSARY. In fact I think it is a
mistake to have divided callables into two types. The 'function' should
have been dropped and a 'delegate' should have been initializable from
any sort of callable in D, including class member function, class
non-member functions ( static member functions ), global functions,
nested functions, and any other callable in D I might have missed.

This is what C++ currently achieves through boost::function/boost::bind
and it would be remarkable if D did not achieve the same sort of
interoperability.

Making a delegate be able to represent any callable type of the given
parameters/return-type enables any function-like object to be treated as
a first-class language construct in D. Having two distinct callable
types simply bifurcates the effectiveness of this concept. Needless to
say, implementing callbacks, as well as events ( signals/slots ) having
to deal with two different callable types whereas one would do nicely,
is not the best design for a language. A callback in general does not
care whether the handler is a member function, global function, or any
other type of callable, it just makes the call and lets the callback
handler ( "functor" if you will ) do what it wants with it.

Perhaps there are some implementation issues regarding this which I do
not understand but these should be overcome in order to present a single
interface to the callable concept. Perhaps this has been
discussed ad nauseam on this NG already, so please correct me if I do
not understand all the ramifications of uniting all callable types under
the single idea of 'delegate' while perhaps keeping 'function' around
merely for backward compatibility with old code until eventually it is
dropped.
Jan 28 2008
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Edward Diener wrote:
 Perhaps there are some implementation issues regarding this which I do
 not understand but these should be overcome in order to present a single
 interface to the callable concept. Perhaps this has been
 discussed ad nauseam on this NG already, so please correct me if I do
 not understand all the ramifications of uniting all callable types under
 the single idea of 'delegate' while perhaps keeping 'function' around
 merely for backward compatibility with old code until eventually it is
 dropped.

To merge the two requires the generation of thunks at runtime to manipulate the parameters and calling convention. It's doable, but not simple.
Jan 28 2008
next sibling parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
Walter Bright wrote:
 Edward Diener wrote:
 Perhaps there are some implementation issues regarding this which I do
 not understand but these should be overcome in order to present a single
 interface to the callable concept. Perhaps this has been
 discussed ad nauseam on this NG already, so please correct me if I do
 not understand all the ramifications of uniting all callable types under
 the single idea of 'delegate' while perhaps keeping 'function' around
 merely for backward compatibility with old code until eventually it is
 dropped.

To merge the two requires the generation of thunks at runtime to manipulate the parameters and calling convention. It's doable, but not simple.

Perhaps allowing a delegate to point to a free function is enough to make people happy? It sure would please me ;) L.
Jan 29 2008
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Lionello Lunesu wrote:
 Walter Bright wrote:
 To merge the two requires the generation of thunks at runtime to 
 manipulate the parameters and calling convention. It's doable, but not 
 simple.

Perhaps allowing a delegate to point to a free function is enough to make people happy? It sure would please me ;)

Me too, but it still changes the calling convention, and still needs a thunk.
Jan 29 2008
parent "Craig Black" <cblack ara.com> writes:
"Walter Bright" <newshound1 digitalmars.com> wrote in message 
news:fnmrjo$109m$1 digitalmars.com...
 Lionello Lunesu wrote:
 Walter Bright wrote:
 To merge the two requires the generation of thunks at runtime to 
 manipulate the parameters and calling convention. It's doable, but not 
 simple.

Perhaps allowing a delegate to point to a free function is enough to make people happy? It sure would please me ;)

Me too, but it still changes the calling convention, and still needs a thunk.

I don't understand why this is so difficult. There already exists a function template that can be used to convert a function pointer to a delegate. BCS showed it to me a while back. Why not just have DMD call such a function to convert function pointers to delegates? T delegate(A) Fn2Dg(T, A...)(T function(A) f) { struct tmp { T ret(A args){ return (cast(T function(A))this)(args); } }; return &(cast(tmp*)f).ret; } -Craig
Jan 29 2008
prev sibling parent Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Lionello Lunesu wrote:
 Walter Bright wrote:
 Edward Diener wrote:
 Perhaps there are some implementation issues regarding this which I do
 not understand but these should be overcome in order to present a single
 interface to the callable concept. Perhaps this has been
 discussed ad nauseam on this NG already, so please correct me if I do
 not understand all the ramifications of uniting all callable types under
 the single idea of 'delegate' while perhaps keeping 'function' around
 merely for backward compatibility with old code until eventually it is
 dropped.

To merge the two requires the generation of thunks at runtime to manipulate the parameters and calling convention. It's doable, but not simple.

Perhaps allowing a delegate to point to a free function is enough to make people happy? It sure would please me ;)

Yes, that is the essence of my suggestion. There is no need to have a separate 'function' as callback since a 'delegate' should be able to encompass any non-member function also. After all if a 'delegate' needs both an object pointer and and a ( member ) function pointer, and a 'function' just needs a function pointer, then for a delegate encompassing a free function the object pointer is just null. As I originally stated, setting up a callback does NOT care whether what is called is a member function or a non-member function, any more than an event ( a signal ) cares whether event handlers ( slots ) are member functions or free functions. Furthermore, with both 'function' and 'delegate' representing callables, setting up a callback, or an event, means having to cater to two different types of callables. This just complicates what should be a single concept and implementation. I am sure Walter understands all this and the difficulty in having a single callback has nothing to do with the validity of the idea and everything to do with the implementation. Yet clearly it is a much superior design to the separate 'function'/'delegate' dichotomy.
Jan 29 2008
prev sibling next sibling parent reply Leandro Lucarella <llucax gmail.com> writes:
Walter Bright, el 28 de enero a las 18:51 me escribiste:
 Edward Diener wrote:
Perhaps there are some implementation issues regarding this which I do
not understand but these should be overcome in order to present a single
interface to the callable concept. Perhaps this has been
discussed ad nauseam on this NG already, so please correct me if I do
not understand all the ramifications of uniting all callable types under
the single idea of 'delegate' while perhaps keeping 'function' around
merely for backward compatibility with old code until eventually it is
dropped.

To merge the two requires the generation of thunks at runtime to manipulate the parameters and calling convention. It's doable, but not simple.

And please, don't forget we need plain function pointers to interact with C. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- Todos en el mundo somos grasas, no hago distinción de sexo y raza, sólo que algunos lo disfrutan y otros no pueden evitarlo.
Jan 29 2008
next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Leandro Lucarella wrote:
 Walter Bright, el 28 de enero a las 18:51 me escribiste:
 Edward Diener wrote:
 Perhaps there are some implementation issues regarding this which
 I do not understand but these should be overcome in order to
 present a single interface to the callable concept. Perhaps this
 has been discussed ad nauseam on this NG already, so please
 correct me if I do not understand all the ramifications of
 uniting all callable types under the single idea of 'delegate'
 while perhaps keeping 'function' around merely for backward
 compatibility with old code until eventually it is dropped.

manipulate the parameters and calling convention. It's doable, but not simple.

And please, don't forget we need plain function pointers to interact with C.

Yes, we do need that. But plain function pointers seem to get more and more relegated to only being for that, much as char* pointers have given way to char[], and you only see char* when interfacing with C.
Jan 29 2008
prev sibling parent reply Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Leandro Lucarella wrote:
 Walter Bright, el 28 de enero a las 18:51 me escribiste:
 Edward Diener wrote:
 Perhaps there are some implementation issues regarding this which I do
 not understand but these should be overcome in order to present a single
 interface to the callable concept. Perhaps this has been
 discussed ad nauseam on this NG already, so please correct me if I do
 not understand all the ramifications of uniting all callable types under
 the single idea of 'delegate' while perhaps keeping 'function' around
 merely for backward compatibility with old code until eventually it is
 dropped.


And please, don't forget we need plain function pointers to interact with C.

You might need plain function pointers but you do not need 'function'. A 'delegate' which encompassed a 'function', with the object pointer part of the delegate being null in that particle case, should be implicitly convertible to a C function pointer.
Jan 29 2008
next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Janice Caron wrote:
 On 1/30/08, Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote:
 You might need plain function pointers but you do not need 'function'. A
 'delegate' which encompassed a 'function', with the object pointer part
 of the delegate being null in that particle case, should be implicitly
 convertible to a C function pointer.

In general, the compiler cannot tell at compile time whether or a not a value is null at runtime (though in an expression like &f it obviously can), so I don't think it can be quite that automatic. Nonetheless, I'm inclined to agree that we probably don't need the "function" keyword at all. delegate f; oldFashionedCFunction( f.funcptr );

But we still need typedefs and declarations. How do you declare oldFashionedCFunction() ? At the moment, you can have an extern(C) function pointer, ... but what is an extern(C) delegate ? AFAIK, all delegates use the D calling convention. This is not true for functions. Clearly several things would need to change.
Jan 30 2008
next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Janice Caron wrote:
 On Jan 30, 2008 8:36 AM, Janice Caron <caron800 googlemail.com> wrote:
 On Jan 30, 2008 8:16 AM, Don Clugston <dac nospam.com.au> wrote:
 How do you declare
 oldFashionedCFunction() ?

extern(C) void (*callback)(int,int);


That's just 'function', using the hideous C syntax.
 Or, for any delegate dg,
 
     typeof(dg.funcptr) callback;

That only works if you can have extern(C), extern(Windows) delegates. The problem is that, because of calling conventions, not all function pointers can be expressed by dg.funcptr. The existing delegates are therefore not a superset of function pointers.
Jan 30 2008
next sibling parent reply "Joel C. Salomon" <joelcsalomon gmail.com> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Janice Caron wrote:
 On Jan 30, 2008 11:17 AM, Don Clugston <dac nospam.com.au> wrote:
     extern(C) void (*callback)(int,int);



Yes, that is precisely my suggestion. I see that as an advantage, not a disadvantage, because it would encourage people to use "delegate", unless they absolutely couldn't.

 On the other hand, if you want to interface with C, then you shouldn't
 be surprised if you have to use hideous C syntax.

I’d go a step further: If you’re interfacing to a C function, you presumably have its declaration handy -- in C syntax. Why have a keyword that’s only useful in the one circumstance where it’s not needed? - --Joel -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHoKpPzLx4GzBL9dYRArmAAKDP1DkAj5w6CAaoPHttIXaevdFLygCgkNF6 aSjVbilEUnDyoiSr4lbn6xw= =yN2s -----END PGP SIGNATURE-----
Jan 30 2008
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Joel C. Salomon wrote:
 Janice Caron wrote:
 On the other hand, if you want to interface with C, then you shouldn't
 be surprised if you have to use hideous C syntax.

I’d go a step further: If you’re interfacing to a C function, you presumably have its declaration handy -- in C syntax. Why have a keyword that’s only useful in the one circumstance where it’s not needed?

How about when you're interfacing with a different language and are using the C calling convention as a 'lingua franca'? (Or even linking DMD-compiled code and GDC-compiled code, since they use different calling conventions for D functions)
Jan 30 2008
prev sibling parent Don Clugston <dac nospam.com.au> writes:
Janice Caron wrote:
 On Jan 30, 2008 11:17 AM, Don Clugston <dac nospam.com.au> wrote:
     extern(C) void (*callback)(int,int);



Yes, that is precisely my suggestion. I see that as an advantage, not a disadvantage, because it would encourage people to use "delegate", unless they absolutely couldn't. All I'm saying is, if you're working in D alone, you can get along just fine using "delegate" instead of "function", and therefore the keyword "function" is unnecessary. On the other hand, if you want to interface with C, then you shouldn't be surprised if you have to use hideous C syntax. So we /could/ ditch "function" and have one fewer keyword.

Ah, OK -- that's a reasonable argument. Certainly it does seem that 'function' is becoming a 'foreign' concept to D; you almost always want to use 'delegate' instead. Note (1) 'function' has a different meaning inside is() expressions. alias void function(int,int) Foo; static assert (is(Foo == function)); // fails! Note (2) function pointers do pop up in other places even if you program exclusively in D, for example in reflection (compile time and runtime). The vtable is full of function pointers, not delegates.
Jan 30 2008
prev sibling parent Leandro Lucarella <llucax gmail.com> writes:
Janice Caron, el 30 de enero a las 08:36 me escribiste:
 On Jan 30, 2008 8:16 AM, Don Clugston <dac nospam.com.au> wrote:
 How do you declare
 oldFashionedCFunction() ?

The old fashioned way? extern(C) void (*callback)(int,int);

That's that the keyword function is for. What's the point of removing it if we need it? -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- "CIRILO" Y "SIRACUSA" DE "SEÑORITA MAESTRA": UNO MUERTO Y OTRO PRESO -- Crónica TV
Jan 30 2008
prev sibling parent Edward Diener <eddielee_no_spam_here tropicsoft.com> writes:
Janice Caron wrote:
 On 1/30/08, Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote:
 You might need plain function pointers but you do not need 'function'. A
 'delegate' which encompassed a 'function', with the object pointer part
 of the delegate being null in that particle case, should be implicitly
 convertible to a C function pointer.

In general, the compiler cannot tell at compile time whether or a not a value is null at runtime (though in an expression like &f it obviously can), so I don't think it can be quite that automatic.

But it can generate code which checks at run-time if this is the case and takes the correct action. In the case of converting a delegate which has a non-null value as the object pointer, the code generated if one tries to cast it to a plain C function pointer could throw an exception.
Jan 30 2008
prev sibling next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 1/30/08, Edward Diener <eddielee_no_spam_here tropicsoft.com> wrote:
 You might need plain function pointers but you do not need 'function'. A
 'delegate' which encompassed a 'function', with the object pointer part
 of the delegate being null in that particle case, should be implicitly
 convertible to a C function pointer.

In general, the compiler cannot tell at compile time whether or a not a value is null at runtime (though in an expression like &f it obviously can), so I don't think it can be quite that automatic. Nonetheless, I'm inclined to agree that we probably don't need the "function" keyword at all. delegate f; oldFashionedCFunction( f.funcptr );
Jan 29 2008
prev sibling next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On Jan 30, 2008 8:16 AM, Don Clugston <dac nospam.com.au> wrote:
 How do you declare
 oldFashionedCFunction() ?

The old fashioned way? extern(C) void (*callback)(int,int);
 what is an extern(C) delegate ?

How can that even make sense? C does not have delegates.
Jan 30 2008
prev sibling next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On Jan 30, 2008 8:36 AM, Janice Caron <caron800 googlemail.com> wrote:
 On Jan 30, 2008 8:16 AM, Don Clugston <dac nospam.com.au> wrote:
 How do you declare
 oldFashionedCFunction() ?

The old fashioned way? extern(C) void (*callback)(int,int);

Or, for any delegate dg, typeof(dg.funcptr) callback;
Jan 30 2008
prev sibling next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On Jan 30, 2008 11:17 AM, Don Clugston <dac nospam.com.au> wrote:
     extern(C) void (*callback)(int,int);


That's just 'function', using the hideous C syntax.

Yes, that is precisely my suggestion. I see that as an advantage, not a disadvantage, because it would encourage people to use "delegate", unless they absolutely couldn't. All I'm saying is, if you're working in D alone, you can get along just fine using "delegate" instead of "function", and therefore the keyword "function" is unnecessary. On the other hand, if you want to interface with C, then you shouldn't be surprised if you have to use hideous C syntax. So we /could/ ditch "function" and have one fewer keyword.
Jan 30 2008
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Edward Diener wrote:
 Perhaps there are some implementation issues regarding this which I do
 not understand but these should be overcome in order to present a single
 interface to the callable concept. Perhaps this has been
 discussed ad nauseam on this NG already, so please correct me if I do
 not understand all the ramifications of uniting all callable types under
 the single idea of 'delegate' while perhaps keeping 'function' around
 merely for backward compatibility with old code until eventually it is
 dropped.

To merge the two requires the generation of thunks at runtime to manipulate the parameters and calling convention. It's doable, but not simple.

Can't say I've thought this through, but what if delegates simply worked for all functions with the extern (D) calling convention, regardless of scope? That would cover the vast majority of cases, and make other calling conventions somewhat of a special case, which they are anyway. Sean
Jan 30 2008
prev sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On Jan 30, 2008 11:24 PM, Edward Diener
<eddielee_no_spam_here tropicsoft.com> wrote:
 But it can generate code which checks at run-time if this is the case
 and takes the correct action. In the case of converting a delegate which
 has a non-null value as the object pointer, the code generated if one
 tries to cast it to a plain C function pointer could throw an exception.

Good point. Along similar lines, the compiler could generate code which checks for null dereferences, but I don't see that happening anytime soon. :-( These are exactly the sort of things that ought to be in debug (but not release) builds (IMO).
Jan 30 2008
prev sibling next sibling parent BCS <ao pathlink.com> writes:
Reply to Edward,

 As I was reading about delegates and the syntax to initialize them I
 was thinking that such similar natural syntax had been suggested to
 C++ many times over the years. Of course delegates already have their
 antecedents in C++ Builder closures and .Net delegates among others.
 My reaction to delegates and their elegant syntax was "bravo, of
 course" but I also had the reaction of why are there both 'delegate'
 and 'function'.
 
 Later in the pdf documentation I saw the a note that the future might
 see 'delegate' and 'function' folded into a single callable type. My
 reaction to this is: ABSOLUTELY NECESSARY. In fact I think it is a
 mistake to have divided callables into two types. The 'function'
 should have been dropped and a 'delegate' should have been
 initializable from any sort of callable in D, including class member
 function, class non-member functions ( static member functions ),
 global functions, nested functions, and any other callable in D I
 might have missed.

The issue I see is that delegates are 64 bits (assuming a 32bit system) and functions are 32 bits. To maintain link compatibility with C, the 32bit plain-old-function-pointer form is needed. But it can't (cleanly) be used with delegates that need that extra 32bits for the context/this pointer.
Jan 28 2008
prev sibling parent reply Russell Lewis <webmaster villagersonline.com> writes:
I agree with the sentiment that it should be possible to implicitly cast 
a function to a delegate, but I don't think that merging the two is the 
best idea.

First, in my experience with D, I find that function pointers are rather 
rare.  As you get to use D more and more, you end up using delegate 
literals (or delegates to member functions) more and more, while 
pointers to ordinary functions become rare.  Sure, I just had to handle 
function pointers a few days ago, but that was noteworthy as the first 
time I had had to use them in a long time.  And what I did was just 
generate a template which automatically created a delegate out of it. :)

So, IMHO, having both doesn't add too much complexity to code, 
particularly if the implicit cast thing works some day.

The reason that I think that they should be retained (in addition to the 
C interop argument already posted) is that D aims to be a language that 
allows you to go down to the bare metal and write "C code in D."  If we 
had only delegates, and not function pointers, then we are hamstringing 
somebody who wants to write a bare-metal, fast-as-possible D program.

For me, with my toy programs, I'll keep using delegates for just about 
everything. :)

Edward Diener wrote:
 As I was reading about delegates and the syntax to initialize them I was
 thinking that such similar natural syntax had been suggested to C++ many
 times over the years. Of course delegates already have their antecedents
 in C++ Builder closures and .Net delegates among others. My reaction to
 delegates and their elegant syntax was "bravo, of course" but I also had
 the reaction of why are there both 'delegate' and 'function'.
 
 Later in the pdf documentation I saw the a note that the future might
 see 'delegate' and 'function' folded into a single callable type. My
 reaction to this is: ABSOLUTELY NECESSARY. In fact I think it is a
 mistake to have divided callables into two types. The 'function' should
 have been dropped and a 'delegate' should have been initializable from
 any sort of callable in D, including class member function, class
 non-member functions ( static member functions ), global functions,
 nested functions, and any other callable in D I might have missed.
 
 This is what C++ currently achieves through boost::function/boost::bind
 and it would be remarkable if D did not achieve the same sort of
 interoperability.
 
 Making a delegate be able to represent any callable type of the given
 parameters/return-type enables any function-like object to be treated as
 a first-class language construct in D. Having two distinct callable
 types simply bifurcates the effectiveness of this concept. Needless to
 say, implementing callbacks, as well as events ( signals/slots ) having
 to deal with two different callable types whereas one would do nicely,
 is not the best design for a language. A callback in general does not
 care whether the handler is a member function, global function, or any
 other type of callable, it just makes the call and lets the callback
 handler ( "functor" if you will ) do what it wants with it.
 
 Perhaps there are some implementation issues regarding this which I do
 not understand but these should be overcome in order to present a single
 interface to the callable concept. Perhaps this has been
 discussed ad nauseam on this NG already, so please correct me if I do
 not understand all the ramifications of uniting all callable types under
 the single idea of 'delegate' while perhaps keeping 'function' around
 merely for backward compatibility with old code until eventually it is
 dropped.
 

Jan 28 2008
parent reply BCS <ao pathlink.com> writes:
Reply to Russell,

 what I did was just generate a template which automatically created a
 delegate out of it.
 

somthing like this? // IFTI might want somthing else\ here R delegate(A) convert(R, A...)(R function(A) fnp) { struct S { // "this" is a function pointer not a S* R do(A a) { U u; u.s = this; retrun s.f(a);} } union U { S* s; R function(a) f; } U u; u.f= fnp; retrun &u.s.do; } note it never news anything! *Untested, but I've used the idea befor.*
Jan 28 2008
parent reply Russell Lewis <webmaster villagersonline.com> writes:
Yeah, I've seen people use the union magic to make it work without a 
new.  It's a cool trick, but it makes me squirm when I think about 
portability.  So I use a general version, using closures (note that my 
template uses a fixed "void" return code...previous posts in the NG can 
show you how to IFTI non-void return codes):

void delegate(TPL) convert(TPL...)(void function(TPL) func)
{
   return delegate void(TPL args)
          {
            func(args);
          };
}

// note that 'func' is put on the heap automatically by the closure
// mechanism in the compiler.

BCS wrote:
 Reply to Russell,
 
 what I did was just generate a template which automatically created a
 delegate out of it.

somthing like this? // IFTI might want somthing else\ here R delegate(A) convert(R, A...)(R function(A) fnp) { struct S { // "this" is a function pointer not a S* R do(A a) { U u; u.s = this; retrun s.f(a);} } union U { S* s; R function(a) f; } U u; u.f= fnp; retrun &u.s.do; } note it never news anything! *Untested, but I've used the idea befor.*

Jan 29 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Russell Lewis" <webmaster villagersonline.com> wrote in message 
news:fnnivs$11k$1 digitalmars.com...
 Yeah, I've seen people use the union magic to make it work without a new. 
 It's a cool trick, but it makes me squirm when I think about portability. 
 So I use a general version, using closures (note that my template uses a 
 fixed "void" return code...previous posts in the NG can show you how to 
 IFTI non-void return codes):

 void delegate(TPL) convert(TPL...)(void function(TPL) func)
 {
   return delegate void(TPL args)
          {
            func(args);
          };
 }

 // note that 'func' is put on the heap automatically by the closure
 // mechanism in the compiler.

For those who aren't aware, this will only work in D2, not D1. In D1 you'll probably get an access violation upon attempting to call the returned delegate.
Jan 29 2008