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