[1008] in java-interest
Fully dynamic message dispatch considered safe and useful.
daemon@ATHENA.MIT.EDU (Charles L. Perkins)
Wed Aug 16 18:53:39 1995
Date: Wed, 16 Aug 95 15:17:46 -0400
From: "Charles L. Perkins" <clp@home.HarvardSq.com>
To: java-interest@java.sun.com
Cc: clp@home.HarvardSq.com
From: Terence John Parr <parrt@parr-research.com>
Date: Wed, 9 Aug 1995 19:04:29 -0500
Subject: Re: Dynamic Method Invocation
> Is it or will it ever be possible to invoke a method dynamically using a
> variable?
I hope not. That would require that the interpreter know how to compile
Java; further, can you say "self-modifying code"? I knew you could.
I've let a lot of comments like the above pass, but finally I've gotten fed up.
I'd like to start a new thread to replace operator overloading, which is:
--> Why doesn't Java support the "perform:" of Objective-C and Smalltalk? <--
Before you answer, listen to these standard objections:
(1) It is unsafe.
It *is* safe, despite the numerous dodges that various Java developers
(even inside Sun) have tried to throw at me. If it were not safe, the javac
compiler could not turn text into bytecodes for message dispatch, could it?
As a minimal proof of being able to do it safely, include javac in the R/T.
(2) It will be too slow at run-time to make it safe.
Since the run-time *already* has some procedure it does to be sure that
whatever the compiler generates is safe, this is another red-herring. The
only interesting cases are:
(a) the message name attempted does not exist (is not in the DB of names)
(b) the message name attempted is not legal to call (private/protected)
Both of these could be solved by the following scheme:
Take the string and perform the same DB/hashtable lookup the compiler does
at R/T. This throws an exception if the name is not understood or if the
class of the receiver doesn't have allow that message to be sent to it
(either due to not being in its method dictionary or not being legal to
send (private/protected)); all the info. needed for this test will be in
memory since that info. is in the .class file loaded for each class. You
will have to do the protected/private test by hand in the R/T, but you can
tell when you have to do this by using a new bytecode for perform/dispatch.
If you don't like the above (too many exceptions being thrown at R/T) then
how about this one? Use the above scheme, but force the user of the perform
message to generate the selector at compile time (like @selector() of Obj-C)
so that now the compiler can do the hashtable-lookup at compile-time and
verify it is a legal name. There's still a R/T exception for private/protected
violations, or for sending a name to the wrong class, but I'll bet the latter
has to exist already in the R/T.
Remember, this doesn't need to be as fast as Java's standard dispatch, you
would not use it for more than a small % of all your dispatches in a typical
program, but it *can* be quite fast (evidence Obj-C and ST-80 implementations).
(3) You don't really need it. You should use interfaces, or....
Another red-herring. Sure, if all you want to do is enumerate lists of objects
and send simple messages to them, I suppose for some it's about as easy to say:
for (Enumerator e = Enumerator(list); e.hasMoreElements; e = e.nextElement)
e.simpleMessage(arg);
as it is to say:
list.allElementsPerform("simpleMessage", arg);
(BTW, I think the latter is cleaner.)
But what about more complex cases like:
-- you want to use a class with a callback several times from the same object
but it's callback "message" can only be implemented once! without being
able to name the callback message, you have to use clumsy global state info.
-- you want to allow the user to interactively type in any of a large number
of possible names for functions to apply to a graphical object; perform:
dispatches directly to the message desired without any by-hand DB lookup.
particularly useful if the names are coming from, say, a menu system auto-
generated by an Interface Builder (a la NeXTSTEP's I.B.)
-- you want to automatically "stitch together" various existing APIs written
by others; e.g., you're down-the-middleware: you must dynamically generate
tables that map incoming message names to outgoing message names; especially
easy to do if you have a doesNotUnderstand exception, but impossible to do
(without the full compiler inside) without perform:
-- you want to create proxy objects that don't inherit from Object but want
to pass along all their messages to another object, over the network, etc.
here, being able to send messages "apparently not understood" is key, as
is having a doesNotUnderstand exception [metaclasses can also be used here]
-- <I'm sure other avid Smalltalkers can think of even more cases...>
Interfaces *are* quite useful if you treat them as a cheap resource and make
a lot of them. (E.g., use one for every time you want to use a simple perform:
you pass the object instead of the message name, but in the context that knows
what interface (message) to send to it.) This does not, however, solve the
above problems.
(4) Is is a complication to Java's simple language model.
I claim the reverse! If you allow new("ClassName") already, and you have all
classes dynamically loadable, and you allow limited dynamic method lookup
already, it seems *odd* to not include the natural extension of that lookup,
in analogy with new(<String>).
In a lot of ways, Java is like a mini-Smalltalk masquerading as a C++ subset.
That's OK with me, I love Smalltalk, but if it is leaning in that direction
it should not delete one of the most powerful features of Smalltalk without
very good reason.
It's a little like implementing Lisp but removing Eval; you can do it (as
Dylan has done), but you have to have good reasons. And the limited performs
I suggest in (2) above are much easier and faster to implement than Eval.
By the way, I love an awful lot of Java, and have a feeling that there *are*
good answers to some of my points above. I would just like to hear them.
I'm not trying to suggest that Java *must* have perform, but I'm trying to
get some of the language authors to explain their reasons for dropping this
powerful and historically useful feature.
Charles L. Perkins
Virtual Rendezvous
-
Note to Sun employees: this is an EXTERNAL mailing list!
Info: send 'help' to java-interest-request@java.sun.com