DaveAKing / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

Checked exception bridge for lambdas #1670

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Following-up on 
http://java8blog.com/post/37385501926/fixing-checked-exceptions-in-java-8 we 
need the ability to wrap a checked exception thrown by the lambda, then 
unwrapping the same type on the outside.

The blog I linked to only covers half of the equation (wrapping checked 
exceptions) but fails to unwrap them back on the outside (which we should do).

Original issue reported on code.google.com by cow...@bbs.darktech.org on 15 Feb 2014 at 9:26

GoogleCodeExporter commented 9 years ago
Can you give some more detail about what the new methods would look like? Would 
we be adding mapWithException, filterWithException, and so on for each 
lambda-accepting method, or is there a generic solution?

Original comment by cpov...@google.com on 18 Feb 2014 at 3:39

GoogleCodeExporter commented 9 years ago
Good point. I initially thought there would be a generic solution, but you made 
me realize that between the time we catch an exception, and the time we throw 
it, we must invoke some variable method.

Is there a way for us to leverage method handles somehow? In an ideal world, a 
user would invoke this:

  Throwables.propagate(Files::walk, myLambda, IOException.class)

and under the hood, this would translate to:

try
{
  Files.walk(() ->
  {
    try
    {
      myLambda();
    }
    catch (IOException e)
    {
      throw new CheckedExceptionWrapper(e);
    }
  );
}
catch (CheckedExceptionWrapper e)
{
  throw (IOException) (e.getCause();
}

I'm not familiar enough with method handles. Do you think this would be 
possible?

Original comment by cow...@bbs.darktech.org on 18 Feb 2014 at 6:39

GoogleCodeExporter commented 9 years ago
I'm not sure what you mean about method handles.  There are conceivable types 
for which this would work, it just looks like it'd require a "block with 
checked exception" interface...?

Original comment by lowas...@google.com on 18 Feb 2014 at 6:42

GoogleCodeExporter commented 9 years ago
Re: method handles, I'm saying that for this to be generic you will need to 
construct method invocations and catch/throw using dynamically-constructed 
types.

Notice how above I wrote that the user passes in Files::walk and you translate 
this into an actual method invocation under the hood. I'm wondering if you 
could do the same for throwing/catching IOException.

What did you have in mind (provide pseudocode) for "block with checked 
exception"?

Original comment by cow...@bbs.darktech.org on 18 Feb 2014 at 6:48

GoogleCodeExporter commented 9 years ago
You might be able to reuse interfaces more effectively here, somewhere...

interface ThrowingRunnable<X extends Exception> {
  public void run() throws X;
}

<X extends Exception, Y extends Exception> 
   void Throwables.propagate(
      Consumer<Runnable> consumer,
      ThrowingRunnable<X> operation,
      Class<X> clazz) {
   try {
     consumer.accept(() -> {
       try {
         operation.run();
       } catch (Exception e) {
         if (clazz.isInstance(e)) {
           throw new CheckedExceptionWrapper(e);
         }
       }
     });
   } catch (CheckedExceptionWrapper e) {
     throw clazz.cast(e.getCause());
   }
}

Original comment by lowas...@google.com on 18 Feb 2014 at 6:54

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<issue id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:10

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:17

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:07