Fully dynamic d by opDotExp overloading

Christopher Wright dhasenan at gmail.com
Sun Apr 19 10:12:33 PDT 2009


Michel Fortin wrote:
> The thing is that the name of that "catchAllHandlerFunc" function needs 
> to be standardised for it to work with runtime reflection.

I agree with this wholeheartedly.

However, opDotExp would be hamstringed if it were made to serve this 
function.

Since classes can implement interfaces, you could expose an interface 
IDispatch or the like. This doesn't suffice for structs, though.

> Let's look at the swizzle case. You want a class or a struct with a 
> function for every permutation of "xwyz". Beside doing that manually, 
> here's what you can do:
> 
> Solution A: use a mixin. This will add 256 functions to your struct, and 
> those functions will appear in the functionList used by 
> invokeViaReflection.
> 
> Solution B.1: use a templated catch-all function, and use the name to 
> instanciate the catch-all. Calling the function will work at compile 
> time, but at runtime invokeViaReflection is left in the dust.
> 
> Solution B.2: in addition to the templated catch-all function in B.1, 
> add a runtime catch-all. This is about twice the work, but 
> invokeViaReflection can work with those functions.

The standard form will be something like:
class Dispatch : IDispatch
{
    auto opDotExp(string name)(...) { return dispatch(name, _arguments, 
_argptr); }
    auto dispatch(string name, ...)
    {
       // do stuff
    }
}

This isn't much added work.

> Now, let's look at the proxy case, where you want to forward function 
> calls to another object. In fact, there are two variant of this case: 
> one where you know the type at compile-time, one where you don't (you 
> only know the base class) but still want to forward all calls.
> 
> Solution A: use a mixin. The mixin will create a wrapper function for 
> all functions in the wrapped object it can find using compile-time 
> reflection, and those functions will appear in the functionList used by 
> invokeViaReflection.

That's a lot of work, but it can get you a performance increase in the 
case where you know something about the class at compile time (for 
instance, you have an object that implements a particular interface, but 
you want to call non-interface functions via the wrapper).

Of course, you could manually forward methods as well and get the same 
performance increase. But that would be more difficult to write.

> Note that I'm not that much against a templated opDot, I just want to 
> point out its drawbacks for reflection. I'm also unconvinced of its 
> usefulness considering you can do the same things better using mixins 
> leaving only the runtime case to be solved, where you are better served 
> without a template anyway.

Well, you can do the same things with some other advantages with mixins, 
but it's harder to write.

I think the appropriate solution is to add a solver to the compiler that 
can determine valid inputs for opDotExp and, if that set is below a 
threshold, unroll the template into regular member functions.

Or, you know, just implement a static foreach that you can use in 
templates. And anything else that we can think of that's reasonable to 
make the mixin solution easier to work with.

If that's accomplished, there'd be no reason to have opDotExp as a template.



More information about the Digitalmars-d mailing list