【发布时间】:2011-09-02 18:42:35
【问题描述】:
前段时间,Oracle 决定在 Java 8 中添加闭包是个好主意。我想知道与从第一天起就关闭的 Scala 相比,那里的设计问题是如何解决的。
引用javac.info 的未决问题:
方法句柄可以用于函数类型吗? 如何使其工作尚不清楚。一个问题是方法句柄会具体化类型参数,但会干扰函数子类型化。
我们能否摆脱“抛出”类型参数的显式声明? 这个想法是在声明的绑定是检查异常类型时使用析取类型推断。这不是严格向后兼容的,但不太可能破坏真实的现有代码。然而,由于语法上的歧义,我们可能无法摆脱类型参数中的“抛出”。
在旧式循环索引变量上禁止 @Shared
处理定义多个方法的接口(如 Comparator),除了其中一个方法外,所有这些接口都将由继承自 Object 的方法实现。 “单一方法的接口”的定义应仅计算不会由 Object 中的方法实现的方法,并且如果实现其中一个方法将实现所有方法,则应将多个方法计为一个。主要是,这需要更精确地说明接口只有一个抽象方法意味着什么。
指定从函数类型到接口的映射:名称、参数等。 我们应该完全精确地指定从函数类型到系统生成接口的映射。
类型推断。 需要扩充类型推断规则以适应异常类型参数的推断。同样,闭包转换使用的子类型关系也应该体现出来。
省略的异常类型参数有助于改进异常透明度。 也许使省略的异常类型参数意味着界限。这可以通过添加新的泛型异常参数来改造没有异常类型参数的现有泛型接口,例如 java.util.concurrent.Callable。
函数类型的类字面量是如何形成的? 是 #void().class 吗?如果是这样,如果对象类型被擦除,它是如何工作的?是#?(?).class 吗?
系统类加载器应动态生成函数类型接口。 与函数类型对应的接口应该由引导类加载器按需生成,以便在所有用户代码之间共享。对于原型,我们可能让 javac 生成这些接口,以便原型生成的代码可以在库存 (JDK5-6) 虚拟机上运行。
必须每次对 lambda 表达式求值都产生一个新对象吗? 希望不会。例如,如果 lambda 没有从封闭范围捕获变量,则可以静态分配它。类似地,在其他情况下,如果 lambda 未捕获循环内声明的任何变量,则可以将其移出内部循环。因此,如果规范不承诺 lambda 表达式结果的引用标识,那将是最好的,这样编译器就可以完成这样的优化。
据我了解,2.、6. 和 7. 在 Scala 中不是问题,因为 Scala 不像 Java 那样将检查异常用作某种“影子类型系统”。
剩下的呢?
【问题讨论】:
标签: scala closures language-design java-8