Points about language support for 292

John Rose John.Rose at Sun.COM
Fri May 1 12:06:51 PDT 2009

On Apr 30, 2009, at 3:15 PM, Alex Buckley wrote:

> Hi John,
> 1.1: "The complete lack of supertypes makes it an unusual type, on a  
> par
> with Object."
> But InvokeDynamic is defined as a class with a superclass of Object a
> few lines earlier. The text in () looks redundant.

My bad; I missed the edit; fixed now in the wiki.  I replaced that  
parenthesis by:

> (Note that InvokeDynamic is not useful as a reference type.  Like  
> java.util.Collections, it is a non-instantiated class.)

Some other comments about InvokeDynamic are also cleaned up, as  
replacing "abstract" by "non-instantiated".

> 1.5: As the JVM executes, checked exceptions may be produced by any
> invokedynamic call.
> Please don't put "JVM" and "checked exceptions" in the same sentence!
> More importantly, I don't agree with "the possibility of a missed  
> catch
> of a checked exception is not considered to be a hazard." An exception
> handler further up the stack that catches unchecked exceptions will  
> miss
> it, and the program will in all likelihood stop.

I'll reformulate; of course it's a hazard, but the point is that  
dynamically checked languages do not have statically checked  
exceptions, and (therefore) neither does InvokeDynamic.

Dynamic languages rely on programmer foresight (that estimable  
faculty) to put the right catches around potentially throwing code.   
So must the loophole into Java.

> In other words, this is a relaxation too far of static exception
> checking. One option is to have InvokeDynamic.foo() claim to throw all
> possible checked exceptions. If one actually leaks back to the call  
> site
> from a dynamic language's runtime, it should be caught right there.

Should be; and the programmer who is using InvokeDynamic will  
doubtless do so, or bear the consequences of buggy code.

Neal's suggestion (based on his experience with closure types) is more  
feasible.  The return type parameter (for both MethodHandle and  
InvokeDynamic) should be able to express the checked exceptions thrown  
by the call.  I wish we had something like optional throws clauses for  
type variables but we don't.

As grody hack, more optional type parameters could express, to the  
surrounding Java code, the checked exceptions emanating from an  

InvokeDynamic.<void, IOException, AnotherBadException>foo(bar, baz);

But this seems pointless to me.  Since it's a dynamic call, the  
quality of this additional information cannot be determined  

(The Java compiler could decorate the call site with elaborate runtime  
checks.  See below for details.  I this would be wasted effort.)

The design as it stands lets the exceptions flow out of the call site,  
without attempting to document them there.  It allows the programmer  
to write catches for the relevant ones, and assumes that the  
programmer will write all the necessary ones, without help from static  
exception checking:

try { InvokeDynamic.<void>foo(bar, baz); }
} catch (IOException x) { /* programmer-written logic here*/ }
} catch (AnotherBadException x) { /* more logic here*/ }

That's status quo for dynamic languages!

> Another option, and perhaps a better one since it partitions
> InvokeDynamic off from checked exceptions entirely, is to specify that
> its infinite static methods can throw only unchecked exceptions (or  
> one
> in particular, if you like). An implementation would have to wrap
> checked exceptions.

Sorry, wrapping checked exceptions is a non-starter for 292.  Wrapping  
of all sorts is one of the reasons reflection is unusably slow for  
dynamic language implementation.

-- John

P.S.  Here's what checked exception verification would look like:

try { InvokeDynamic.<void, IOException, AnotherBadException>foo(bar,  
// the following catches could be invisibly added to every  
invokedynamic instruction generated by javac:
} catch (IOException x) { throw x; }
} catch (AnotherBadException x) { throw x; }
} catch (RuntimeException x) { throw x; }
} catch (Exception x) { throw new InternalError("didn't you forget  
something?", x); }

More information about the coin-dev mailing list