Guava中的任何东西都类似于Functional Java的效果?

Guava中的任何东西都类似于Functional Java的效果?

问题描述:

我知道纯函数式编程的目标之一是消除可变性,从而排除副作用。但是让我们面对现实吧,即使存在所有的函数式编程库,Java也不是一种函数式语言。事实上,似乎有些FP库知道并期待这一点。例如,在Functional Java中,有 效果 类。在Jedi FP库中,有 Command 界面。这允许您 - 除其他外 - 将类型安全的命令模式应用于 Iterable 的元素,而不需要讨厌的for循环样板。

I know one of the goals of pure functional programming is to eliminate mutability, and therefore to preclude side-effects. But let's face it, Java is not a functional language even with all of the functional-programming libraries that exist. In fact it seems that some of the FP-libraries know and expect this. For instance in Functional Java, there is the Effect class. In the Jedi FP library, there is the Command interface. This allows you to -- among other things -- apply a command pattern with type-safety to elements of an Iterable without the nasty for-loop boilerplate.

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

所以问题是,番石榴中有类似的东西吗?

So the question is, is there anything like that in Guava?

在接受澄清后接受回复

我正在开发框架,有助于解决大多数Java FP库中固有的垂直问题,在某些情况下。所以我 not 实际上是如上所示的代码示例:即明确声明一个新的类实现 Command 及其所有垂直噪声icky-ness,只是为了在声明之后立即应用它。

I am developing a framework that helps with the "vertical problem" inherent in most Java FP-libraries, under a certain set of circumstances. So I would not actually make the code example as shown above: i.e., explicitly declare a new class implementation of Command with all of its vertical-noise icky-ness, simply for the purpose of immediately applying it right after the declaration.

我在考虑实际命令模式的方式更多,其中可能有几个可能的命令在其他地方声明,并且只有其中一个被传递到想要迭代应用它的代码中。此外,我的框架的目标是使创建功能接口对象(函数,谓词,命令,其他简单的lambda)更加惯用,而不是简单地将垂直问题移动到其他地方。我早就意识到这不在番石榴的范围内。但是由于其他FP库中有类似Command的接口,我只是想知道Guava中是否存在模拟。

I was thinking more along the lines of the actual command pattern, where there may be several possible commands declared elsewhere, and only one of them gets passed into the code which wants to apply it iteratively. Furthermore, the goal of my framework is to make it more idiomatic to create functional-interface objects (functions, predicates, commands, other simple lambdas) without simply moving the vertical problem elsewhere. I have long realized this is not within the scope of Guava. But as Command-like interface are available in other FP libraries, I just wanted to know if an analog existed in Guava.

一个更完整的代码示例,使用我的框架,可能是这样的:

A more complete code example, using my framework, might be something like this:

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


不!

Guava项目负责人Kevin Bourrillion对Guava的功能特性说:

Kevin Bourrillion, the Guava project lead, has said on Guava's functional features:


语法很糟糕。与此同时,这些东西现在,一直都是,并且永远只是一个权宜之计,直到正确的语言变化出现,此时我们终于可以真正决定最佳语法并开始功能式编程实际上,在Java中让生活更美好一次。所以我不确定将多少精力放入Function / Predicate中;它更多是因为它必须是库,而不是因为我们认为它是皇冠上的宝石。

"The syntax sucks. At the same time, this stuff is now, has always been and will always be nothing but a stopgap measure until the right language change can come along, at which time we can finally really decide on the optimal syntax and have functional-style programming start actually making lives better in Java for once. So I’m undecided how much effort to put into the Function/Predicate stuff; it’s in the library more because it sort of had to be, not so much because we think it’s a crown jewel."

我们将可能会在Java 8出现时显着改变我们的策略,但这还不会有一段时间。

We will probably change our strategy significantly when Java 8 comes along, but that won't be for a while yet.

另外,我们还没有发现很多用例认为你描述的 Command 界面是最好的解决方案。例如,我们认为您的上述代码可以更好地编写为

Also, we haven't found many use cases for which we think the Command interface you describe would be the best solution. For example, we think that your above code would be much better written as

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

老式的方式。我们可能会相信 Command 的优点,但我认为for-each用例几乎总是以老式的方式做得更好。

the old-fashioned way. We could potentially be convinced of the merit of Command, but I think the "for-each" use case is almost always better done the old-fashioned way.