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; }