Inferring that what exceptions are thrown from a lambda
Neal Gafter
neal at gafter.com
Fri Sep 6 12:31:12 PDT 2013
This is what I called "exception transparency" when BGGA (the "closures"
project) was developed. As I understand it, it was considered for project
lambda and rejected. As much as you and I would like these things to work
"as they obviously should", that does not appear to be a goal of project
Lambda.
See, for example,
http://mail.openjdk.java.net/pipermail/lambda-spec-comments/2012-October/000001.html
Cheers,
Neal
On Thu, Sep 5, 2013 at 7:22 PM, Stuart Marks <stuart.marks at oracle.com>wrote:
> Applying this to the OP's example, this would propagate "throws
> Exception" out to the callers, forcing them to catch or to throw
> Exception themselves. That's not what the OP wanted. Instead, the
> example using a lambda that throws IOException should only be forced to
> handle or declare IOException, and the example using a lambda that
> doesn't throw any checked exceptions shouldn't have to deal with
> exceptions at all.
>
> With the new inference work in the compiler, the additional "X extends
> Throwable" type argument seems to do the trick for some common cases. (I
> tend to prefer type variable X -- "exception" -- over E, since E is
> already used for enums and for collection element types.) It doesn't
> work if the lambda throws multiple different checked exception types.
> For example, the following doesn't work:
>
> public void multiple() throws ExecutionException,
> InterruptedException {
> String result = tryRepeatedly(10, () -> {
> if (/*condition*/)
> throw new ExecutionException(null);
> else
> throw new InterruptedException();
> });
> }
>
> Here, the compiler infers the least upper bound for the lambda's
> exception type, which in this case is Exception, so that's what has to
> be listed in the throws clause instead of listing multiple exception
> types. Oh well.
>
> s'marks
>
>
>
> On 9/4/13 7:22 PM, Howard Lovatt wrote:
> > It is generally easier to do this:
> >
> > public interface Action<T> {
> > T run() throws Exception;
> > }
> >
> > Which is what Callable does, infact the above is Callable apart from
> > the name changes (Callable -> Action, call -> run).
> >
> >
> > On 5 September 2013 06:11, Stuart Marks <stuart.marks at oracle.com
> > <mailto:stuart.marks at oracle.com>> wrote:
> >
> > On 8/31/13 11:04 AM, Esko Luontola wrote:
> > > But if the lambda doesn't thrown anything, the compiler thinks
> > that the
> > > method may throw the most generic exception. The following code
> > fails to
> > > compile with "error: unreported exception Throwable; must be
> > caught or
> > > declared to be thrown"
> > >
> > > public void doesNotCompile() {
> > > String result = Resilient.tryRepeatedly(10, () ->
> > "result");
> > > }
> >
> > A change to support this went in fairly recently. This now
> > compiles for
> > me using JDK 8 b105. It fails with the error you mention when using
> > older builds, e.g., JDK 8 b88, which is one I happened to have lying
> > around. (Note, I am referring to JDK 8 builds, not Lambda builds.)
> >
> > I believe that if a lambda throws no checked exceptions, and its
> > functional interface method is declared "throws E", then E is now
> > inferred to be RuntimeException.
> >
> > s'marks
> >
> >
> >
> >
> > --
> > -- Howard.
>
>
>
More information about the lambda-spec-observers
mailing list