I use a number of libraries in Clojure that produce higher order functions that conform to the "clojure.lang.IFn" interface.
It has multiple arity overloads, I.e. the interface looks something like:
public interface IFn extends Callable, Runnable{
public Object invoke() ;
public Object invoke(Object arg1) ;
public Object invoke(Object arg1, Object arg2) ;
public Object invoke(Object arg1, Object arg2, Object arg3) ;
.... etc.
public Object applyTo(ISeq arglist) ;
}
Will I be able to use objects of this type directly in Java 8 as callable lambda functions?
What do you mean, use objects of this type as callable lambdas?
In very simple cases, Java 8 lambdas can be thought as syntactic sugar + some type inference for anonymous classes for certain type of interfaces, namely functional interfaces [1]:
The interface ActionListener, used above, has just one method. Many common callback interfaces have this property, such as Runnable and Comparator. We'll give all interfaces that have just one method a name: functional interfaces.
Remark: lambdas are really not just a sugar; internally they are implemented differently than anonymous classes, and there are also some semantic differences; see this excellent answer on ProgrammersExchange for more on this matter. However, this is not really important in context of this question and answer.
Anywhere where a value of some functional interface is expected (method argument, local variable, field declaration etc.) it will be possible to use short syntax for creating an entity resemling anonymous class implementing this method, that is, a lambda expression:
Runnable r = () -> {
System.out.println("Hi");
};
// Equivalent to
Runnable r = new Runnable() {
public void run() {
System.out.println("Hi");
}
};
public interface Function<F, T> {
T call(F arg);
}
Function<String, char[]> c = s -> ("<" + s + ">").toCharArray();
// Equivalent to
Function<String, char[]> c = new Function<>() {
public char[] call(String s) {
return ("<" + s + ">").toCharArray();
}
};
So your question can only be interpreted in the following way: is it possible to create objects of type IFn
using Java 8 lambda syntax?
The answer is no. Lambda syntax is possible only with functional interfaces. clojure.lang.IFn
is not a functional interface because it contains much more than single method, so it won't be possible to do something like
IFn f = (String s) -> s.toLowerCase();
No, it seems you can not use clojure functions as if they are also valid java lambdas. Clojure's IFn does not conform to java's "lambda" functional interfaces as defined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With