Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using scala.Future with Java 8 lambdas

The scala Future class has several methods that are based on functional programming. When called from Java, it looks like using lambdas from Java 8 would be a natural fit.

However, when I try to actually use that, I run into several problems. The following code does not compile

someScalaFuture.map(val -> Math.sqrt(val)).
       map(val -> val + 3); 

because map takes an ExecutionContext as an implicit argument. In Scala, you can (usually) ignore that, but it needs to be passed in explicitly in Java.

someScalaFuture.map(val -> Math.sqrt(val),
                    ec).
       map(val -> val + 3,
           ec);

This fails with this error:

error: method map in interface Future<T> cannot be applied to given types;
[ERROR] val),ExecutionContextExecutor
  reason: cannot infer type-variable(s) S
    (argument mismatch; Function1 is not a functional interface
      multiple non-overriding abstract methods found in interface Function1)
  where S,T are type-variables:
    S extends Object declared in method <S>map(Function1<T,S>,ExecutionContext)
    T extends Object declared in interface Future 

If I actually create an anonymous class extending Function1 and implement apply as such:

    someScalaFuture.map(new Function1<Double, Double>() {
            public double apply(double val) { return Math.sqrt(val); }
        },
        ec).
        map(val -> val + 3,
            ec);

I get an error that

error: <anonymous com.example.MyTestClass$1> is not abstract and does not override abstract method apply$mcVJ$sp(long) in Function1

I have not tried implementing that method (and am not sure if you can even implement a method with dollar signs in the middle of the name), but this looks like I am starting to wonder into the details of Scala implementations.

Am I going down a feasible path? Is there a reasonable way to use lambdas in this way? If there is a library that makes this work, that is an acceptable solution. Ideally, something like

import static org.thirdparty.MakeLambdasWork.wrap;
...
   wrap(someScalaFuture).map(val -> Math.sqrt(val)).
         map(val -> val + 3);
like image 593
Troy Daniels Avatar asked Sep 11 '15 15:09

Troy Daniels


1 Answers

The scala-java8-compat library provides interoperability between Scala 2.11 and Java 8 lambdas.

like image 66
Seth Tisue Avatar answered Oct 03 '22 06:10

Seth Tisue