JDK 7出人意料将增加“简单”闭包,发布时间推迟至明年底
作者 Dionysios G. Synodinos 译者 张龙 发布于 2009年11月25日 上午12时29分
近日Mark Reinhold在Devoxx的演讲中宣布JDK 7将增加闭包特性。由于添加了这个饱受 争议的特性,JDK 7的发布时间将推迟至明年9月左右。
Project Coin(旨在对Java 7进行小幅度的语言改进)的首席工程师Joseph D. Darcy已经确认语言的下一版本将增加某些“轻量级”的闭包:
… JDK 7将增加闭包特性,增加的闭包要比BGGA(即Closures for the Java Programming Language,译者注)所提出的闭包更小巧,因此JDK 7的发布时间将推迟至明年9月左右:
Alex Miller也参加了此次大会,他指出尽管过去社区已经给出了3个不同的提案,但Sun对于闭包的态度还是很消极:
我真的是无语了。这几年Sun总强调大家并没有就闭包这个问题达成共识,也延误了成立闭包JSR或专家组的时机,但实际情况却是社区已经给出了3个提案,每个提案都有相应的原型。
就在Mark Reinhold宣布这个消息不久,Neal Gafter(已有的3个闭包提案中BGGA提案的发起人之一,BGGA其实就是4位发起者名字的首字母缩写,他们是Bracha、Gafter、Gosling和von der Ahé)就发布了一个“简化的提案”:
该提案有如下变化之处:
- 将控制调用(control invocation)语法移到另一个单独的规范中。
- 将术语闭包字面量(closure literal)替换为lambda表达式(lambda expression)。
- 我们检查了lambda表达式的语法,从Clang借鉴了一些精华。现在有两种形式的lambda表达式:expression lambda拥有控制表达式,而statement lambda拥有控制语句。
- 将术语闭包对象(closure object)替换为函数对象(function object)。
- 将术语闭包变换(closure conversion)替换为lambda变换(lambda conversion),而控制调用语法将拥有一个单独的块变换(block conversion)。
- 为return语句增加新的语义:现在可以从statement lambda中返回了。
- 将java.lang.Unreachable改为java.lang.Nothing,这一点借鉴了Scala。
- 移除对类型名null的支持。之前的版本在没有异常抛出时将null作为一个异常类型的占位符。现在,类型Nothing可以满足这个要求。
- 受限制检查。受限制(restricted)与不限制(unrestricted)的函数类型与闭包概念已经被移除了。现在所有的lambda表达式都是受限制的。我们可以通过控制调用语法将此前规范中的不限制闭包传递给方法。
- 增加方法引用支持:我们通过一个新引入的符号#将对方法的引用当作函数看待。该语法来源于javadoc中的交叉引用和FCM提案。
JDK 7这种突然间的变化令Fabrizio Giudici等很多人对决策的过程表示怀疑:
我不想谈论这么做好不好(你知道在我听说该提案既不是BGGA,也不是CICE,而是一个新提案时我就觉得这不是一件好事)。我只是惊诧于仅仅几周后Java 7就与Project Coin(知名的最终5提案)达成了一致,某些人几乎是瞬间就改变了主意。这到底是怎样的一个决策过程呢?
啊哈,我知道了——他们一定是投硬币决定的,现在我终于知道Project Coin项目名字的来历了。我担心Java 7会变成最混乱的一个Java版本——如果你想干掉Java的话这么做倒是不错(因为现在大家的争论点还不算太多,比如Oracle的收购或是关于Jigsaw/OSGi的争论)。
与此类似,Geertjan Wielenga也觉得增加闭包这个决定太出人意料了:
如果没人想问决策的过程是怎样的,为何得出这个结论的话,那这绝对是个好消息,或许还是最好的消息呢。首先,我们拥有一堆提案,但根本没人看。其次,突然间我们就拥有了“简单闭包”(我想知道是否现有的所有提案都可以叫做“复杂闭包”呢。难道简单就是闭包的全部么?)。好吧,闭包看起来会很简单,没有非局部的return(non-local return)、没有控制语句、无法访问非final变量。我还是想问一下,到底是如何得出这个决定的?
Cay Horstmann针对这个新的BGGA提案给出了几个用例,与FCM提案何其相似:
我们真的不知道Sun到底想搞什么。之前我粗略地分析了一下BGGA 0.6a提案,总体上来说与现在的BGGA差不多。没人反对BGGA与FCM的相似性。没有非局部的return、用于lambda的#。由于需要在捕获前用@Shared注解突变变量(mutated variable),人们在编写之前可能需要考虑再三。foreach(@Shared String v : values) funcs.add( #() => v);
Alex Miller提到JDK发布的延期可能会让其他特性有机会加到最终的发布中,比如ParallelArray程序库,它为映射、过滤以及Java对象数组的裁剪提供了一套函数风格的API:
我在QCon上与Bob Lee聊了一会,他觉得JDK 7的延期有可能会将ParallelArray纳入进来并使用新的闭包支持。
张旋(zxsoft)
如对本文有什么疑问,请在下面写下留言,谢谢!