September 11, 2006
Marcio wrote:
>> In C++ I used my "fastdelegate" template (on CodeProject) to hack delegates into C++. This lets you do something vaguely like:
>>
> [...]
>> Then, you can write
>>
>> void myfunc(StringWithURL s) {}
>>
>> and it will accept anything derived from String. 
> 
> 
>    I want existing String objects, belonging to class String, to be able to understand asURL. Not a new class. Unless I misunderstood your explanation. My understanding is that "derived from String" does not include String.

Sorry, my wording was poor. Anything implicitly convertible to String will be implicitly convertible to StringWithURL. This obviously includes String itself.

>> It's unnecessarily inefficient, though -- not as lightweight as it should be.
>> Also things like delete don't work (they don't delete the base class).
> 
> 
>   If you could just add methods to the class, these methods would behave the same as the ones defined in the class itself. No speed penalty.

Yes. That was a limitation of C++ templates, I think you could do better in D with the same idea. With my technique it would not be possible to add data members, though.

>   The feature request is quite simple actually. Allow a class C to be defined not just in 1 file, but in N files. From many fragments. A class is never a closed module in this case.

Simple to request, complicated to implement I would guess. Something defined in a DLL surely has to be a closed module?

>>>     Another scenario I would be interested to see working is how I can have Object return false to "isWidget" but a Widget class return true.
>>
>> Yeah, that's very common. Some cases can be done very easily:
>>
>> template (X)
>> void myfunc(X x) {
>> static if ( is( x.isWidget ) ) {
>>     ...
>> }
>> }
>>
>> but if you don't know the type at compile time, you're stuck.
>    Yeah, I'd rather just rely on polymorphism. Which can be done if the source of a class can be split across multiple files. These extra methods become regular methods, not second class.
> 
>> It's very imperfect, but might generate ideas.
> 
> 
>    Indeed. But in my mind, a compiler can do lots of interesting things after compiling the full program. These extension methods would not be hard. There are also all sorts of polymorphism optimizations that can be done. SmartEiffel (used to be SmallEiffel) does all sorts of virtual call optimizations because it can do a global analysis of thr code (something Java can't do, for example, because of thr dynamic class loading etc). Sometimes their compiler eliminates 98% of virtual calls. It generates amazingly fast code.

I believe D is designed to allow those optimisations.

>   Anyway, just to say that if you are compiling a program to generate an EXE, with no fancy dynamic loading etc, it should be possible to do these global analysis and therefore also allow methods to be added from different places. Like extending a framework by adding methods to base classes so that all subclasses now receive the extra behavior. And that includes Object itself.

I'd rather do that stuff with templates. If mixins were a little more powerful, you could use them to add the extra functionality to base classes. If you look at the example in the gaming article, it's clear that the designer of the framework *knows* where the extra functionality is going to be required. The problem is that the language doesn't give a nice way of expressing it.

September 21, 2006
Sorry to drag this up again, but I was out of town for a while.

Marcio wrote:
>   You want String to have a new method, say asURL. Or findReplace. Or whatever. Not a new String subclass. You want to add functionality to String.
> 
>   You want all objects to understand dumpOn (aStream). Say you are writing a persistent framework. You need to add methods to Object.

The thing that I don't get about this is what happens if code A and code B both decide to add an 'asURL' method to String?  Or 'dumpOn' to Object?

With a function [e.g. asURL(aString), dumpOn(obj,stream)] these things can be disambiguated by using fully qualified names [myModule.asURL, yourModule.asURL], but if you go and make it a method on the base class [String.asURL()], you're effectively putting in the namespace of that class, right?  And so you're suceptible to name clashes with anyone who wants to add methods to the same class.

Do you make it so that the lookup is done local to the calling module? So that if module B adds a method to String, only module B can see that method?  I don't see how that can work implementation-wise, though.  How will I know to use that table instead of the default one when handed some arbitrary pointer to an object that may or may not be derived from String?  -- without adding a bunch of extra explicit type checks, I mean.

It's a very interesting idea. I guess I still just don't see how it can work in a statically typed language where dispatch is done with vtable lookup.

--bb
1 2 3
Next ›   Last »