The Final(ize) Challenge

Steven Schveighoffer schveiguy at yahoo.com
Mon May 18 11:30:37 PDT 2009


On Mon, 18 May 2009 12:12:40 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> Ok, now with the advent (or rediscovery) of allMembers which I had no  
> idea existed, we're ready to start some serious butt-kick reflection  
> facilities.
>
> For starters, I'd like to present you with the following challenge.  
> Given any class C, e.g.:
>
> class C
> {
>      void foo(int) { ... }
>      int bar(string) { ... }
> }
>
> define a template class Finalize(T) such that Finalize!(C) is the same  
> as the following hand-written class:
>
> final class FinalizeC : C
> {
>      final void foo(int a) { return super.foo(a); }
>      final int bar(string a) { return super.bar(a); }
> }
>
> Finalize is cool when you need some functionality from an exact class  
> and you don't want to pay indirect calls throughout. All calls through  
> Finalize!(C)'s methods will resolve to static calls.
>
>
> Have at it!

1 minor issue, if super.foo(a) calls bar, then it's still a virtual call...

Not that it's not a good idea, but you might get a lot less mileage out of  
it than you think.

I think you'd need compiler help to get rid of that problem.  It'd be like  
a flattening of a class to recompile all base class virtual calls with the  
notion that any internal calls it makes are final.  If you casted to a  
base class, the initial call would be virtual, but the internal calls  
would be nonvirtual.  This would be impossible unless you had the source  
to all the base classes, it might just be better to do it as a separate  
code-generator tool.

Back to your idea...

This feature that you suggest seems very trivial for the compiler to  
implement, while extremely hard to do it via reflection.  I've longed for  
this for a while:

interface I
{
   int foo();
}

class A
{
   int foo() {return 0;}
}

class B: A, I
{
   alias A.foo foo;
}

which makes B implement the interface by simply copying the vtable entry  
 from A's.  This even saves on the double call (having a derived class  
function that simply calls the base class function).  You could then allow:

class B: A, I
{
   final alias A.foo foo;
}

and the compiler knows it doesn't need a virtual lookup.  Then the  
template to do it to all virtual methods would be trivial.

-Steve



More information about the Digitalmars-d mailing list