Java 8以一流公民的身份跳舞吗?

C.B*_*.B. 1 java first-class-functions java-8

因此,我中的函数程序员喜欢像python这样的语言,它们将函数视为一等公民。看起来Java 8承受了压力,而诸如lambda表达式和方法引用之类的“已实现的”东西则被淘汰了。

我的问题是,Java是否正在使用一流的函数,或者这真的只是语法糖,以减少实现匿名类/接口(如可运行的接口)所需的代码量?(我的肠子说后者)。

我理想的情况

Map<String,DoubleToDoubleFunc> mymap = new HashMap<String,DoubleToDoubleFunc>();
...
mymap.put("Func 1", (double a, double b) -> a + b);
mymap.put("Func 2", Math::pow);
...
w = mymap.get("Func 1")(y,z);
x = mymap.get("Func 2")(y,z);
Run Code Online (Sandbox Code Playgroud)

Edw*_*rzo 6

Java 8中没有函数结构类型。但是Java一直都有一流的对象。实际上,它们已被用作替代方案。从历史上看,由于缺乏一流的功能,到目前为止,我们所做的就是将功能包装在对象中。这些是著名的SAM类型(单个抽象方法类型)。

所以,代替

function run() {}
Thread t = new Thread(run);
Run Code Online (Sandbox Code Playgroud)

我们的确是

Runnable run = new Runnable(){ public void run(){} };
Thread t = new Thread(run);
Run Code Online (Sandbox Code Playgroud)

也就是说,我们将函数放在对象内部,以便能够将其作为值传递。因此,很长一段时间以来,一流的对象一直是替代解决方案。

JDK 8简单地简化了实现此概念的过程,它们将这种类型的包装器接口称为“功能性接口”,并提供了一些语法糖来实现包装器对象。

Runnable run = () -> {};
Thread t = new Thread(run);
Run Code Online (Sandbox Code Playgroud)

但最终,我们仍在使用一流的对象。它们具有与一流函数相似的属性。它们封装了行为,可以作为参数传递,也可以作为值返回。

lambda邮件列表中, Brian Goetz很好地解释了激发该设计的一些原因。

按照我们今天讨论的思路,这是我们前进的方向。我们探索了“也许lambdas应该只是内部类实例,那真的很简单”之路,但最终走到了“函数是语言未来的更好方向”的位置。

这种探索是分阶段进行的:首先在EG成立之前在内部,然后在EG讨论问题时再次进行。以下是我对此问题的立场。希望这可以填补规范目前所说的内容与我们对此所说的内容之间的一些空白。

关于lambda是否是对象的问题主要归结为诸如“ lambda到底是什么”,“ Java为什么将从lambda中受益”以及最终“如何最好地发展Java语言和平台”这样的哲学问题。

Oracle的立场是,为了保持竞争力,Java必须(当然,要谨慎地)发展。当然,这是困难的平衡行为。

我相信,Java演进的最佳方向是鼓励一种更具功能性的编程风格。Lambda的作用主要是支持开发和使用更具功能性的库。我提供了例如filter-map-reduce的示例来说明这一方向。

生态系统中有大量证据支持以下假设:如果给定了易于实现的工具,那么面向对象的程序员就可以使用功能技术(例如不变性),并将其工作成为面向对象的世界观。 ,因此将编写出更好,更少出错的代码。简而言之,我们相信对Java开发人员来说,最好的办法是使他们轻柔地朝着更具功能性的编程风格发展。我们不会将Java变成Haskell,甚至不会变成Scala。但是方向很明确。

Lambda是这种发展的首付,但这还远未结束。故事的其余部分尚未撰写,但保留我们的选择是我们评估此处所做决策的关键方面。

这就是为什么我一直坚持认为lambda不是对象的原因。我相信“ lambda只是对象”的位置,虽然非常舒适和诱人,但却为语言发展的许多可能有用的方向敲门。

作为一个示例,让我们考虑函数类型。devoxx提供的lambda稻草人具有函数类型。我坚持要删除它们,这使我不受欢迎。但是我对函数类型的反对不是不是我不喜欢函数类型-我喜欢函数类型-而是函数类型与Java类型系统的现有方面进行了激烈的竞争。擦除的函数类型在两个方面都是最糟糕的。因此,我们从设计中删除了此内容。

但是我不愿意说“ Java永远不会有函数类型”(尽管我认识到Java可能永远不会有函数类型。)我相信,要获得函数类型,我们必须首先处理擦除。那可能或不可能。但是在一个复杂的结构类型世界中,功能类型开始变得更加有意义。

世界的lambdas-are-objects视图与这个可能的未来冲突。对世界来说,lambdas-are-functions观点并非如此,并且保持这种灵活性是不让lambdas负担甚至带有客观性的负担的要点之一。

您可能会认为当前的设计与lambda的对象框(SAM类型)紧密相关,因此无论如何都使它们成为有效的对象。但这已从表面区域被仔细隐藏,以使我们将来可以考虑“裸” lambda,或考虑lambda的其他转换上下文,或将lambda更紧密地集成到控制结构中。我们现在没有这样做,甚至没有具体的计划,但是将来有可能做到这一点是设计的关键部分。

我对Java的未来感到乐观,但是要前进,有时我们不得不放弃一些舒适的想法。Lambdas-are函数打开了大门。Lambdas-are-objects将它们关闭。我们更希望看到那些门保持打开状态。