Gregor Richards wrote:
Robert Fraser wrote:
Gregor Richards wrote:
I ran into a situation where I needed (essentially) the visitor pattern, but the visitor pattern sucks, so I wanted to make something like class extensions instead (that is, methods added to a class outside of the class definition).

Of course, it's not possible to do this particularly cleanly, but I made a system that works (albeit using gross string mixins). Essentially, if you have a class A, class B : A, class C : B, you could do something like this:

mixin(extensions("A", "void", "doFoo", "", ""));

mixin(extend("A", "doFoo"));
void A_doFoo(A pthis) {
    /* method for A */
}

mixin(extend("B", "doFoo"));
void B_doFoo(B pthis) {
    /* method for B */
}

Then if you call doFoo(new A()) the call will become A_doFoo(new A()), if you call doFoo(new B()) the call will become B_doFoo(new B()), if you call doFoo(new C()) the call will become B_doFoo(new C()).

If anybody has some improvements, that'd be cool. Maybe you can get rid of the dependence on string mixins ... but I don't think templates quite cut it.

 - Gregor Richards


Pretty cool stuff, but I don't see how this is at all better than the visitor pattern. It is not checked at compile-time (so if you forget to implement one part of the hierarchy, you won't find that out until runtime) and it's likely less efficient, especially for large enough hierarchies (i.e. syntax trees). Where's the happy?

The visitor pattern requires annotating every class in the hierarchy. That's what annoys me about it. I'd like my AST nodes to just be AST nodes.

Yes, calling a function is less efficient. It can probably be improved, I'm just not sure how yet :P

Plus, of course, although the visitor pattern is the example I gave, this is a more general mechanism.

 - Gregor Richards

I agree that this has other uses, so mad props for making it.

For the visitor pattern, I wish there was a "dynamic" type like in C#4. This way, each node needs only to be annotated once for visitors, no matter what they return (with variadic arguments used for parameters, too).

Unrelated (but the main reason I use visitors), I wish D could allow could declaring a virtual function in the class definition but implement it elsewhere (a la C++). So...

module1.d:
----------
module module1;
class A { int foo(int x); }

module 2.d:
-----------
module module2;
import module1;
int A.foo(int x) { return x; }

Reply via email to