[E-Lang] Coming Attractions: Java Overload Resolution
Mark S. Miller
Sat, 24 Mar 2001 08:32:00 -0800
A persistent irritation in using stock Java APIs from E, especially swing,
has been a consequence of the mismatch between the method overloading rules
of the two languages. E overloads based only on arity, and Java overloads
based on the *static* types of the arguments. Ideally, when E calls Java,
it would be good do dispatch to a Java method that won't surprise either the
E or Java programmer, or failing that to throw an exception.
The old E-to-Java spec was that if a Java method was overloaded at all,
calling it by its simple name would throw an exception. Rather, one would
have to call it using typed message name as follows:
def myLabel := E call(<swing:JLabel>, "new(String)",["label text"])
as explained at http://www.skyhunter.com/marcs/ewalnut.html#SEC14 in the
Walnut. This does satisfy the lack-of-surprise principle, but at a great cost.
The obvious alternative, use Java's overload resolution rules, won't work
for E since E has no static argument types, and if you apply Java's rules to
the dynamic argument types you'll get a different answer than you would in
Java. It would be surprising.
In any case, E <= 0.8.9s has not satisfied the above spec. When there are
multiple Java overloads for the same arity, E <= 0.8.9s would make an
arbitrary one available by the simple name. This was a known bug but a bad
one. A program could seem to work fine one day and then fail the next
because it got "lucky" on the arbitrary choice of a Java overload. It was
Rather than fixing this bug, starting with E 0.8.9t, E will now correctly
implements a much less irritating but still unsurprising spec. (Thanks to
MarcS for help figuring out the new spec.) The new spec is that if the
argument list is compatible with exactly one of the overloaded parameter
lists, then that method is executed. Otherwise an exception is thrown.
Despite the urgency of the comm system, I went down that path thinking it
would take about an hour. It took four days, but it's done now. Using
stock Java APIs from E is now *far* more pleasant.
Note: For those writing new Java code with E in mind, it's still recommended
to overload only on arity, not on type. There's a significant new overhead
to doing the runtime type-based overload resolution, while the
non-overloaded case should now be a bit faster.
Does this new rule seem strictly superior and unproblematic to everyone?
What does JPython do?