Что-нибудь в Гуаве похоже на эффект функциональной Java?

Я знаю, что одной из целей чисто функционального программирования является устранение изменчивости и, следовательно, предотвращение побочных эффектов. Но давайте смотреть правде в глаза, Java не является функциональным языком даже со всеми существующими библиотеками функционального программирования. На самом деле кажется, что некоторые FP-библиотеки знают и ожидают этого. Например, в функциональной Java есть класс Effect. . В библиотеке Jedi FP есть интерфейс Command. Это позволяет вам, среди прочего, применять шаблон команды с безопасностью типов к элементам Iterable без неприятного шаблона цикла for.

Command<PhoneNumber> makeCall = new Command<PhoneNumber> {
    public void execute(PhoneNumber p) { p.call(); }
}
List<PhoneNumber> phoneList = ...
FunctionalPrimitives.forEach( phoneList, makeCall );

Так вот вопрос, есть ли что-то подобное в Гуаве?

ОТРЕДАКТИРОВАНО ПОСЛЕ ПРИНЯТИЯ ОТВЕТА ДЛЯ РАЗЪЯСНЕНИЯ

Я разрабатываю фреймворк, который помогает с "вертикальной проблемой", присущей большинству Java FP-библиотек, при определенном наборе обстоятельств. Так что я бы не на самом деле делал пример кода, как показано выше: т. е. явно объявлял новую реализацию класса Command со всеми его неприглядными вертикальными шумами, просто для того, чтобы немедленно применить его правильно после декларации.

Я больше думал о реальном шаблоне команды, где может быть несколько возможных команд, объявленных где-то еще, и только одна из них передается в код, который хочет применять его итеративно. Более того, цель моего фреймворка — сделать создание объектов функционального интерфейса (функций, предикатов, команд и других простых лямбда-выражений) более идиоматичным, не перемещая вертикальную проблему в другое место. Я давно понял, что это не входит в рамки Гуавы. Но поскольку командный интерфейс доступен в других библиотеках FP, я просто хотел знать, существует ли аналог в Guava.

Более полный пример кода с использованием моего фреймворка может выглядеть примерно так:

class Stuff {
    private final Stuff CALLS_TO = callsTo(Stuff.class); // a proxy
    public static final Command<Stuff> CMD1 = commandFor(CALLS_TO.someMethod1());
    public static final Command<Stuff> CMD2 = commandFor(CALLS_TO.someMethod2());

    // methods exist for use elsewhere, but are conveniently also wrapped as commands
    public void someMethod1() {...}
    public void someMethod2() {...}
}

class Activity {
    public void handleIt(List<Stuff> stuffs, Command<Stuff> doCmd) {
        doSomeThings();
        ...
        forEach(stuffs, doCmd);
        ...
        doOtherThings();
    }
}

person Kevin Welker    schedule 01.03.2012    source источник


Ответы (1)


Неа!

Кевин Буррильон, руководитель проекта Guava, сказал о функциональных возможностях Guava:

«Синтаксис отстой. В то же время, этот материал сейчас, всегда был и всегда будет не чем иным, как временной мерой, пока не появится правильное изменение языка, и тогда мы, наконец, действительно сможем выбрать оптимальный синтаксис и начать программирование в функциональном стиле. на самом деле сделать жизнь лучше на Java в кои-то веки. Так что я не решил, сколько усилий нужно приложить к функциям/предикатам; это в библиотеке больше потому, что это должно было быть, а не потому, что мы думаем, что это жемчужина короны ».

Вероятно, мы существенно изменим нашу стратегию, когда появится Java 8, но это произойдет не скоро.

Кроме того, мы не нашли много вариантов использования, для которых, по нашему мнению, интерфейс Command, который вы описываете, был бы лучшим решением. Например, мы думаем, что ваш вышеприведенный код будет намного лучше написан как

for(PhoneNumber phone : phoneList) {
  phone.call();
}

старомодным способом. Потенциально мы могли бы убедиться в достоинстве Command, но я думаю, что вариант использования «для каждого» почти всегда лучше делать старомодным способом.

person Louis Wasserman    schedule 02.03.2012
comment
Почему по старинке лучше для команд, но не лучше для фильтров и преобразований? Кроме того, я знаю, что функциональные возможности рассматриваются как временное решение до Java 8, но вы должны понимать, что Java 8 появится через какое-то время, и ее принятие не будет немедленным. Есть еще проекты с застрявшей Java 5 (к счастью, не мои). - person Kevin Welker; 02.03.2012
comment
Если вы прочитаете руководство пользователя, вы увидите, что мы думаем, что старомодный способ в большинстве случаев лучше подходит для фильтров и преобразований. Не всегда — именно поэтому мы предоставляем эти функции — но большую часть времени. - person Louis Wasserman; 02.03.2012
comment
Кроме того, исходный код сообщения является примером того, что делает Команда Гуавы плачет. - person Justin M. Keyes; 02.03.2012
comment
Я много раз читал этот раздел и в принципе с ним согласен, но считаю, что он слишком расширен. На мой вкус, мой однострочный способ намного читабельнее, чем то, что вы показали, не только потому, что это одна строка, но и потому, что на самом деле он читается более естественно. Пример, приведенный в разделе «Предостережения» руководства пользователя, явно относится к тому, где вы комбинируете функцию и предикат. Также я создаю библиотеку FOSS, которая помогает создавать функции и предикаты, оборачивающие существующие геттеры в одну строку. Так что, безусловно, есть и чистая экономия кода. - person Kevin Welker; 02.03.2012
comment
Да, @Justin, мне всегда нравился этот комментарий, но очевидно, что мой ОП не выглядит ничего похожим на пример, который заставляет их плакать с точки зрения сложности. И в моем комментарии выше вы увидите, что у меня есть предложенное решение вертикальной проблемы. - person Kevin Welker; 02.03.2012
comment
а) Концептуально говоря, Guava нацелена на пользователей с сырым JDK и ни на что другое. б) Я написал раздел руководства пользователя, который мы обсуждаем, и да, ваш пример тоже заставляет меня плакать. c) Если вы действительно хотите провести это обсуждение, мы можем продолжить его на guava-discuss, но SO действительно не место для этого. Я объяснил, что в Гуаве такого нет и почему. - person Louis Wasserman; 02.03.2012
comment
@KevinWelker: между этим и фильтрацией/преобразованием есть огромная разница. Фильтр/преобразование делает то, что нельзя сделать с помощью цикла: они создают представление за постоянное время. Для каждого, как в вашем примере, по своей сути можно заменить циклом. - person ColinD; 02.03.2012
comment
@Louis, спасибо, да, вы действительно четко ответили на вопрос ОП. Я просто застрял в редакционной статье. Я хотел бы рассказать больше о том, к чему я клонил, потому что я вижу, что сам по себе пример кода OP может выглядеть безобразно без контекста. Но я пока отложу и, возможно, выберу разговор в guava-discuss (за которым я внимательно слежу). Спасибо за ответы. - person Kevin Welker; 02.03.2012