Подтвердить что ты не робот

Смогу ли я использовать функции Clojure как Lambdas в Java 8?

Я использую несколько библиотек в Clojure, которые производят функции более высокого порядка, которые соответствуют интерфейсу clojure.lang.IFn".

Он имеет несколько перегрузок arity, I.e. интерфейс выглядит примерно так:

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

Смогу ли я использовать объекты этого типа непосредственно в Java 8 в качестве вызываемых лямбда-функций?

4b9b3361

Ответ 1

Что вы имеете в виду, используйте объекты этого типа как вызываемые lambdas?

В очень простых случаях Java 8 lambdas можно рассматривать как синтаксический сахар + некоторый вывод типа для анонимных классов для определенного типа интерфейсов, а именно функциональные интерфейсы [ 1]:

Интерфейс ActionListener, используемый выше, имеет только один метод. Многие общие интерфейсы обратного вызова имеют это свойство, например Runnable и Компаратор. Мы дадим все интерфейсы, которые имеют только один метод: имя: функциональные интерфейсы.

Примечание: лямбда действительно не просто сахар; внутренне они реализованы иначе, чем анонимные классы, а также есть некоторые семантические различия; см. этот отличный ответ на ProgrammersExchange для получения дополнительной информации по этому вопросу. Однако это не очень важно в контексте этого вопроса и ответа.

В любом месте, где ожидается значение какого-либо функционального интерфейса (аргумент метода, локальная переменная, объявление поля и т.д.), можно будет использовать короткий синтаксис для создания объекта, повторно использующего анонимный класс, реализующий этот метод, то есть выражение лямбда

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

Итак, ваш вопрос может быть интерпретирован только следующим образом: возможно ли создание объектов типа IFn с использованием синтаксиса лямбда Java 8?

Ответ - нет. Синтаксис Lambda возможен только с функциональными интерфейсами. clojure.lang.IFn не является функциональным интерфейсом, потому что он содержит гораздо больше, чем один метод, поэтому не удастся сделать что-то вроде

IFn f = (String s) -> s.toLowerCase();

Ответ 2

Нет, похоже, вы не можете использовать функции clojure, как если бы они также были действительными java lambdas. clojure IFn не соответствует функциональным интерфейсам java "лямбда", как определено.