Exception transparency

Neal Gafter neal at gafter.com
Tue Jun 8 16:44:37 PDT 2010


On Tue, Jun 8, 2010 at 3:54 PM, Alex Buckley <alex.buckley at oracle.com>wrote:

> 2) Denotation of disjunctive types. We allow them only in an exception
> type argument "a.m<throws X|Y>(..)", "new Foo<String, throws X|Y>()",
> etc. In particular, not as the bound of an exception type parameter.
> Moreover, exception type parameters "<throws E> void m();" may only be
> used in exception type arguments (and throws clauses), not as "bare"
> types. With these restrictions, exception type arguments are covariant,
> which is nice. Without these restrictions, you could do this:
>
> interface Function<throws E> { void m(E e); }
> Function<throws IOException> e = #(IOException e){...};
> Function<throws Exception>   f = e;
> try { f.(new Exception()); /* Oops */ } catch (Exception ex) {}
>
> (Actually, I guess we could preserve covariant exception type arguments
> by banning exception type parameters from appearing in contravariant
> locations like method parameters.)
>

Sounds like you're trying to add declaration-site variance to Java (at least
for these type parameters).  It isn't clear how you intend that to work.

Can Function<throws E> appear in an argument position of a method, where E
is a throws-type-parameter of the class containing the method?  If so,
you've undermined exception safety.  If not, you're disallowing a
likely-common programming technique (for example a method like
collection.each).  The problem is that the type parameter has to be
contravariant in this case, but you appear to be proposing to make them
uniformly covariant.

I think your best bet is to NOT have any special variant behavior for these
type parameters.  Wildcards already serve that purpose for SAMs, and
function types can be made naturally variant without either wildcards or
undermining exception safety.

-Neal


More information about the lambda-dev mailing list