A lightweight module for class extensions in D

Nick Sabalausky a at a.a
Sat Dec 6 20:43:03 PST 2008


"Robert Fraser" <fraserofthenight at gmail.com> wrote in message 
news:ghcj02$2kpi$1 at digitalmars.com...
> 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).
>

I'd rather have a type that all other types derive from. Sort of like 
"Object" (or is it "object"?), but serves as the base type for all types, 
not just classes. Not sure if this would be possible though (having vtables 
for every int and char in the program doesn't sound like a good idea ;) ).

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

Sounds like you're thinking of something like C#'s partial classes, but with 
the ability to say "Compiling should fail if I've forgotten to define bodies 
for any of the following functions"? 





More information about the Digitalmars-d mailing list