A lightweight module for class extensions in D

Robert Fraser fraserofthenight at gmail.com
Fri Dec 5 17:02:34 PST 2008


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



More information about the Digitalmars-d mailing list