On Wed, Sep 2, 2009 at 9:49 AM, Daniel Keep<[email protected]> wrote: > > Jarrett Billingsley wrote: >> Well repeat should probably always take a delegate since most likely, >> you're going to be passing it a lambda. However I agree that it would >> be very, very nice to be able to make APIs take just delegates and >> allow functions to be implicitly cast to them. You can already make >> your own thunks, but they're not going to be as efficient as something >> that actually works on an ABI level. > > The problem is that function pointers and delegates have different > calling conventions. You *might* be able to rig up an asm stub that > compensated for the difference... not sure.
Which is why I suggest that the ABI be changed ;) I suppose one method of making their calling conventions compatible would be to pass the delegate's context in what would normally be a scratch register. Delegates/member funcs would store that immediately upon entry, and normal functions wouldn't care if anything were passed. > As it stands, you can just use a function to create the delegate stub > for you; doesn't even require a heap allocation! > > http://gist.github.com/140507 Wow. What a horrible mess of code to do something that should be straightforward. If this is what Andrei is thinking of when he says "introspection", well heh, I'll have no part of it. The comment about tuples not being allowed to contain out and ref is actually not entirely true. Internally type tuples are represented as parameter type tuples, which include the refness, and you can even get .stringofs that include the ref qualifiers. It instead seems that the compiler is buggy and _whether or not the refness of the params in a param tuple is preserved depends on the code using it_. Consider this gem: void foob(T: Ret function(Args), Ret, Args...)(T func) { pragma(msg, ParameterTupleOf!(T).stringof); static void wtf(ParameterTupleOf!(T) args) {} pragma(msg, ParameterTupleOf!(T).stringof); } void blah(int, ref float) {} void aojkjas() { foob(&blah); } Okay, look at foob's body. Both pragmas should print out the same thing, no? They don't. They print: (int, ref float) (int _param_0, float _param_1) WHAT. For one, where did the 'ref' go? For two, where did the names come from? Also, if you look at typeof(&wtf), it's also missing the ref. I'd really, really like to replace your entire module with this: Ret delegate(Args) toDg(T: Ret function(Args), Ret, Args...)(T func) { struct Wrap { T mFunc; Ret call(Args args) { return (cast(T)this)(args); } } Ret delegate(Args) dg; Wrap wrap; dg.ptr = func; dg.funcptr = &wrap.call; return dg; } But I can't. :C
