Troy Daniels Troy Daniels - 9 months ago 28
Scala Question

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);

Answer Source

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