所以我这个函数式程序员喜欢像python这样把函数当作一等公民对待的语言。看起来Java 8屈从于压力,“某种”实现了像lambda表达式和方法引用这样的东西。
我的问题是,Java是否正在使用第一类函数,或者这只是一种语法糖,以减少实现匿名类/接口(如runnable )所需的代码量?(我的直觉是后者)。
我的理想场景
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);发布于 2014-03-27 00:23:14
没有function structural type in Java 8。但是Java一直都有一流的对象。事实上,它们已经被用作另一种选择。在历史上,由于缺少一流的函数,我们到目前为止所做的就是将函数包装在一个对象中。这些是著名的SAM类型(单个抽象方法类型)。
因此,不是
function run() {}
Thread t = new Thread(run);我们有
Runnable run = new Runnable(){ public void run(){} };
Thread t = new Thread(run);也就是说,我们将函数放在对象中,以便能够将其作为值传递。因此,第一类对象长期以来一直是一种替代解决方案。
JDK 8简单地简化了这个概念的实现,它们将这种类型的包装器接口称为“函数接口”,并提供了一些语法糖来实现包装器对象。
Runnable run = () -> {};
Thread t = new Thread(run);但归根结底,我们仍然使用第一类对象。它们具有与一类函数类似的性质。它们封装了行为,可以作为参数传递,也可以作为值返回。
在lambda mailing list中,Brian Goetz很好地解释了激发这种设计的一些原因。
沿着我们今天讨论的路线,让我们来看看我们的发展方向。我们探索了“也许lambdas应该只是内部类实例,这真的很简单”的道路,但最终到达了“函数是语言未来更好的方向”的位置。
这种探索是分阶段进行的:首先在专家组成立之前在内部进行,然后在专家组讨论问题时再次进行。以下是我对这个问题的立场。希望这填补了规范当前所说的和我们所说的之间的一些空白。
关于lambdas是否是对象的问题在很大程度上归结为哲学问题,比如“lambdas到底是什么”,“为什么Java将从lambdas中受益”,以及最终“如何最好地发展Java语言和平台”。
甲骨文的立场是,为了保持竞争力,Java必须--当然是小心翼翼地--发展。当然,这是一个很难平衡的行为。
我相信,Java发展的最佳方向是鼓励更多的函数式编程风格。Lambda的作用主要是支持更多函数式库的开发和使用;我已经提供了像filter-map-reduce这样的例子来说明这个方向。
生态系统中有大量证据支持这一假设,即如果给出工具,面向对象的程序员就会准备好接受函数式技术(例如不变性),并将它们转化为面向对象的世界视图,从而编写出更好、更不容易出错的代码。简单地说,我们认为我们能为Java开发人员做的最好的事情就是给他们一个温和的推动,让他们朝着更函数式的编程风格发展。我们不会把Java变成Haskell,甚至不会变成Scala。但方向是明确的。
Lambda是这一演变的首付,但它远未结束。故事的其余部分还没有写出来,但是保留我们的选择是我们如何评估我们在这里做出的决定的一个关键方面。
这就是为什么我一直坚持lambda不是对象的原因。我相信"lambdas就是对象“的立场,虽然非常舒适和诱人,但却为语言进化的许多潜在有用的方向关上了大门。
作为一个例子,让我们以函数类型为例。在devoxx上提供的lambda strawman具有函数类型。我坚持要删除它们,这让我不受欢迎。但是我对函数类型的反对并不是因为我不喜欢函数类型--我喜欢函数类型--而是因为函数类型与Java类型系统的一个现有方面--擦除--发生了激烈的冲突。擦除的函数类型是这两种情况中最糟糕的。所以我们把这个从设计中去掉了。
但我不愿意说"Java永远不会有函数类型“(尽管我认识到Java可能永远不会有函数类型)。我认为,为了获得函数类型,我们必须首先处理擦除。这可能是可能的,也可能不是。但是在一个具体化的结构类型的世界里,函数类型开始变得更有意义了。
lambdas-are-objects世界的观点与这种可能的未来相冲突。世界的lambdas -are-function视图不是这样的,保留这种灵活性是支持不给lambdas增加负担的要点之一,甚至看起来都是对象性的。
您可能认为当前的设计与lambdas -- SAM类型--的对象框紧密相关--不管怎样,这使它们成为有效的对象。但这已经被小心地隐藏在表面区域,以便我们将来可以考虑“裸露的”lambdas,或者考虑lambdas的其他转换上下文,或者将lambda更紧密地集成到控件构造中。我们现在没有这样做,我们甚至没有这样做的具体计划,但在未来可能这样做的能力是设计的关键部分。
我对Java的未来很乐观,但为了前进,我们有时不得不放弃一些令人舒服的想法。Lambdas-are-function打开了大门。Lambdas-are-object关闭了它们。我们更愿意看到这些门一直开着。
发布于 2014-03-26 23:18:27
它们并不是真正意义上的一流函数。Lambda最终是一个功能接口的实例。但它确实为您提供了一流函数的优势。您可以将其作为参数传递给需要functional接口实例的方法。您可以将其赋给一个变量,在这种情况下,将使用目标类型来推断其类型。你可以从一个方法返回它,等等。
另外,lambdas并不能完全取代匿名类。并不是所有的匿名类都可以转换为lambda。你可以通过this answer获得关于两者之间的区别的很好的解释。所以,没有lambda不是匿名类的语法糖。
发布于 2014-03-26 23:13:57
它不是匿名类的语法糖;它编译成的内容稍微复杂一些。(这并不是说这样做是错误的;任何语言都会有自己的lambdas编译实现细节,而Java的实现细节并不比其他语言差。)
有关完整的、具体的细节,请参阅http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html。
https://stackoverflow.com/questions/22665150
复制相似问题