Walter: extend existing classes with new methods?

Fredrik Olsson peylow at gmail.com
Thu Aug 31 11:51:00 PDT 2006


Bill Baxter skrev:
> Marcio wrote:
>> Walter,
>>
>>    Do you plan to add the ability of adding methods to an existing 
>> class, from another module?
>>
>>    This ties to the issues raised at 
>> http://www.cs.princeton.edu/~dpw/popl/06/Tim-POPL.ppt and the fact 
>> that some languages/systems have had this capability for years 
>> (Smalltalk, for example, and more recently Ruby) with very beneficial 
>> results.
>>
> 
> Smalltalk and Ruby are both dynamically typed languages.  D is 
> statically typed -- that is the type of everything must be known at 
> compile-time, and in particular what methods are present must be known. 
>    AFIK, in D, like in C++, someobject.foo() either fails to compile, or 
> it successully calls foo() at runtime.  There is no runtime check to see 
> if the method exists or not before calling it.  What you're asking for 
> is a really big fundamental change to what D is.
> 
> That said, it might be nice for some aspects of dynamic typing to be 
> built in to the language.  From what I gather, that's one of the 
> strengths of Objective-C, and what makes it a good language for writing 
> GUIs.
> 
In my humble opinion it rocks for writing GUIs. And key value coding, 
binding, and much more that reduce code for managing data and UI sync is 
not only less code, but in most cases no code at all, is as I can see it 
not practically possible without the dynamix message dispatch of 
Objective-C.

Now taking the whole step to Objective-C's lever would be a major task, 
but some run-time info, and possibility to at runtime change the virtual 
methods table would be nice.

I dunno how this could work internally, probably linked list of many 
virtual method tables for each class, allowing "extensions" to add 
batches of new methods.

// Original class
class Foo {
   void doStuff() { writeln("some stuff"); }
}

// New extension to class, added method will be added to all
// subclasses as well, only methods, not instance variables
// can be added.
class Foo (myextension) {
   void doOtherStuff(int a) { writeln("some other stuff:", a); }
}

// And in semi action.
Foo foo = new Foo();
if (foo.respondsTo(doOtherStuff(int)) {
   foo.doOtherStuff(42);
}


But looking at it, I think it would probably be much easier to just 
create Objective-D. The Objective part of Objective-C is very small, and 
could be made as a preprocessor for D to start with, that is exactly 
what was done for Objective-C once upon a time.

The idea of Objective-D intrigues me :). I love Objective-C, but hate 
the C parts...

> So the first step would be to ask if D is going to gain support for 
> basic dynamic method calling, THEN you can ask the question of whether 
> or not adding dynamic methods to existing classes will be allowed.  But 
> I guess if you have dynamic methods, then adding them to classes a la 
> Smalltalk is really not a big deal.  Just a matter of putting another 
> pointer in the class's dynamic method dict.
> 
Unfortunately I do not think it is just that easy, what D, C++, Java, 
etc call OOP is really just syntactic sugar for having functions 
pointers in your structs, and then some fluff. It is not really 
encapsulation, as the caller always needs to know how to call each 
method, often by knowing the exact offset of a methods function pointer 
in a table.

What smalltalk (And Objective-C) does is taking that responsibility away 
from the caller, and instead let the called object be responsible for 
figuring out where the actual implementation is.

As methods could be added by from many modules, and in an undetermined 
order, there is no way to know the exact offset of your added function 
pointer. And you must take the Smalltalk route and actually look up the 
method for each call (And cache the lookups for speed).

As Objective-C does it this method call:
[myObject doSomething:42]; // Think of it as myObject.doSomething(42);
Is in reality rewritten as this:
objc_msgSend(myObject, "doSomething:", 42);
This is not quite true as the C-string "doSomething:" is also guaranteed 
to only exist once in each running process. But in short that is what it 
does.
The function objc_msgSend() will then look up the correct method 
implementation for the method specified in argument 2, for the class of 
the object instance specified in argument 1. If a implementation is 
found this is called with the rest of the arguments, if not the method 
for handling unimplemented methods is called, an error raised, or simply 
do nothing.

Hard to describe in text, maybe this one http://tinyurl.com/kojmm does a 
better job. But in the end it is just a few simple parts, that makes it 
very flexible and powerful. Claiming you know OOP unless you have seen 
the Smalltalk school, is like claiming you know of large cities without 
having seen New York ;).

// Fredrik Olsson



More information about the Digitalmars-d mailing list