Re: Generics vs. Message passing: object namespaces

Robbert Haarman <[email protected]> Sun, 25 Feb 2007 18:58:11 +0100
Newsgroups gmane.comp.lang.lightweight
Message-ID <[email protected]>
On Sun, Feb 25, 2007 at 01:35:54PM +0000, Tom Locke wrote:
> >>And not knowing the type isn't just an unwanted side-effect, it's  
> >>actually the goal. Dynamic OO is about escaping from fragile and  
> >>inflexible type dependencies by using type independent messages  
> >>instead of type dependent functions.
> >
> >You still haven't told us how you disambiguate the draw message  
> >when your object inherits both from a weapon and a picture.  
> >Especially when both draw messages have the same signature.
> 
> If there is type information associated with the *reference*, not the  
> object, e.g. as in a statically typed language, this can be used to  
> disambiguate. C# does this.

I don't know exactly how things work in C#, but I assume about the same 
way as in Java. Now, what you're saying sounds like: suppose we have two 
classes, Picture and Weapon, and a third class, Example, that (somehow) 
inherits the draw method from both of the other classes.

Now, if we have

Picture x =new Example();
x.draw();

we know that draw from Picture is being called, rather than draw from 
Weapon.

However, that does mean that we can't use our Example instance as both a 
Picture and a Weapon in the same code. One way around that would be

Example x = new Example();
((Picture) x).draw();
((Weapon) x).draw());

...and now you're explicitly indicating the namespace, just like you 
would in

(picture:draw x)
(weapon:draw x)

except that the Java code smacks a bit kludgy to me.

> It is conceivable that you could run into a big problem if you face  
> just the right interaction between multiple inheritance, polymorphism  
> and object identity. In practice this seems to be extremely rare. Is  
> this a big enough deal to dismiss object-dispatch in dynamically  
> typed languages? I'd say no, but that's more of a judgement call than  
> an absolute.

I feel that argument is somewhat backwards. We're not dismissing 
object dispatch because of namespace issues, but because generic 
functions are an alternative that is more powerful (I also find them 
more elegant, but I recognize that is subjective).

The argument about name clashes was brought forward as a criticism of 
generic functions, which were supposed to exist in a single namespace, 
whereas, in object dispatch, method names are prefixed by an object, and 
thus divided among multiple namespaces. If anything, object dispatch 
would have an _advantage_ over generic functions here, so it could never 
be a reason to dismiss object dispatch.

Having said that, I don't think the "object dispatch provides more 
namespaces than generic functions" really makes sense. Whether you write 
x.foo or (foo x) is just a matter of syntax. In as far as the type of x 
helps disambiguate foo in the object dispatch case, it also helps 
disambiguate foo in the generic function case.

In CLOS, methods must abide by certain restrictions set out by the 
generic function. For example, the number of arguments must be 
compatible. It is not allowed to define a method that takes three 
arguments for a generic function that only takes two. However, this is 
not an inherent property of generic functions; it's just a limitation of 
CLOS. Without that restriction, I don't see how object dispatch 
disambiguates more cases than generic functions. Generic functions can 
dispatch on the type of their first argument every bit as well as object 
dispatch.

> What I wish I was more clear on, was how often, in GF based OO, one  
> ends up using names that object-dispatch people would consider overly  
> verbose, whether it be draw-gun at the definition site, or gun:draw  
> at the call site.

I think that is more a matter of culture than one of technical 
necessity. For example, names like point-x are common in Lisp programs, 
but not technically necessary (and often abbreviated locally by macros, 
e.g. with-slots). Similarly, I find many (what I consider) overly 
verbose names in Java code that are not dictated by technical necessity 
as far as I know.

Also, as already pointed out, the real savings don't come from using 
shorter identifiers, but from language features that allow programs to 
contain fewer identifiers in the first place.

By and large, I agree with Pascal:

1. Generic functions are desirable. Compared to object dispatch, generic 
functions are more powerful (and expressive).

2. Name clashes can arise. Since this happens regardless of how 
dispatching is done, it is wise to make the namespace facility be 
orthoganal to dispatching, as well.

> I think this is a big reason why language design is such a mysterious  
> art - a deep understanding of the *pragmatic* reality of different  
> styles is only possible with a lot of experience, and few people have  
> the time to gain this experience in a wide range of paradigms.

The task is made even more difficult by the fact that , even if 
something is superior, it will not always be recognized as such. People 
will still cling to the way they're used to doing things, and they might 
complain about your language perceived shortcomings loud enough that it 
keeps other people away from your language. In the end, I think the best 
you can do is make the language the best language for yourself. That 
way, at least you can be happy. The rest of the world can take it or 
leave it.

Regards,

Bob

-- 
"Trying to make bits uncopyable is like trying to make water not wet. The
sooner people accept this, and build business models that take this into
account, the sooner people will start making money again."
	-- Bruce Schneier
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFF4c4zfb9wcmD+WN4RAr1BAJ9SOa46thKDUqgy7GOQjTsI5z4AzwCgowFN
hxu7xSXn6ny7YFWEvJSq8O4=
=8gTL
-----END PGP SIGNATURE-----