[E-Lang] Coming Attractions: Java Overload Resolution

Mark S. Miller markm@caplet.com
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 
fatally surprising.

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?