在Java中关闭Scala vs Closures [英] Closures in Scala vs Closures in Java

查看:255
本文介绍了在Java中关闭Scala vs Closures的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前一段时间,Oracle决定将Closures添加到Java 8将是一个好主意。



引用 打开问题 / strong>来自 javac.info


  1. 方法句柄可以用于函数类型吗?
    如何使用这种方法并不明显。一个问题是,方法句柄reify类型参数,但在某种方式干扰函数子类型。


  2. 我们可以摆脱显式声明throwstype parameters?
    每当声明的bound是被检查的异常类型时,这个想法就是使用disjuntive类型的推理。这不是严格向后兼容,但是不可能破坏真实的现有代码。


  3. 不允许@Shared on old-样式循环索引变量


  4. 可以通过继承自Object的方法来实现。
    具有单个方法的接口的定义应该仅计算方法不会被Object中的方法实现,并且应该将多个方法计为一个,如果实现其中一个方法将实现它们全部。


  5. 指定从函数类型到映射的映射,接口:名称,参数等。
    我们应该完全指定从函数类型到系统生成的接口的映射。


  6. 类型推断。类型推断的规则需要扩充以适应异常类型参数的推断。


  7. 辅助的异常类型参数,以帮助改进异常透明度。
    也许make elided异常类型参数意味着绑定。这可以通过添加一个新的通用异常参数来改进没有异常类型参数的现有通用接口,例如java.util.concurrent.Callable。


  8. 函数类型的类文字是如何形成的?
    是#void()。如果是,如果对象类型被擦除它是如何工作的?是

  9. 系统类加载器应该动态生成函数类型接口。
    对应于函数类型的接口应该由引导类加载器按需生成,因此它们可以在所有用户代码之间共享。对于原型,我们可能有javac生成这些接口,所以原型生成的代码可以运行在库存(JDK5-6)VMs。


  10. 评估lambda表达式每次都会产生一个新对象?
    希望不是。例如,如果lambda从封闭范围中捕获没有变量,那么它可以静态分配。类似地,在其他情况下,如果lambda不能捕获在循环中声明的任何变量,则lambda可以被移出内循环。因此,如果规范不承诺lambda表达式的结果的引用标识,那么最好是这样的优化可以由编译器完成。


根据我的理解2.,6.和7.在Scala中不是一个问题,因为Scala不使用Checked Exceptions作为某种类型的Shadow类型系统,如Java



其余部分呢?

解决方案

)方法句柄可以用于函数类型?



Scala目标JDK 5和6没有方法句柄,所以它没有尝试处理这个问题。



2)我们可以摆脱throws类型参数的显式声明吗? $ b

Scala没有检查异常。



3)在旧式循环索引变量上禁用@Shared。 / em>



Scala没有循环索引变量。但是,同样的想法可以用某种while循环来表达。 Scala的语义在这里很标准。捕获符号绑定,并且如果符号恰好映射到可变参考单元,那么在你自己的头上。



4)处理类似Comparator的接口多于一种方法,除了其中一个来自对象



Scala用户倾向于使用函数(或隐式函数)来强制正确类型的函数一个接口。例如

  [implicit] def toComparator [A](f:(A,A)=> Int)= new Comparator [ A] {
def compare(x:A,y:A)= f(x,y)
}

5)指定从函数类型到接口的映射:



Scala的标准库包含FuncitonN traits ; = N <= 22,规范说函数文字创建了这些traits的实例



6)类型推断。



由于Scala没有选中的异常,因此可以在此类型参数上进行转义整个问题



7)辅助异常类型参数以帮助改进异常透明度。



相同的交易,没有检查的异常。



8)函数类的类文字是如何形成的?是#void()。类吗?如果是,如果对象类型被擦除它是如何工作的?是吗?(?)。类?

  classOf [A = B] //或者等效地
classOf [Function1 [A,B]]

类型擦除是类型擦除。上面的文字产生scala.lang.Function1,而不管A和B的选择。如果你喜欢,你可以写

  classOf [_ => _] //或
classOf [Function1 [_,_]]

9)系统类加载器应该动态生成函数类型接口。



Scala任意地将参数数量限制为最多22个,必须动态生成FunctionN类。



10)每次lambda表达式的求值都会产生一个新对象?

Scala规范并没有说它必须。但是从2.8.1开始,编译器不会优化lambda不能从其环境捕获任何东西的情况。我还没有用2.9.0测试。


Some time ago Oracle decided that adding Closures to Java 8 would be an good idea. I wonder how design problems are solved there in comparison to Scala, which had closures since day one.

Citing the Open Issues from javac.info:

  1. Can Method Handles be used for Function Types? It isn't obvious how to make that work. One problem is that Method Handles reify type parameters, but in a way that interferes with function subtyping.

  2. Can we get rid of the explicit declaration of "throws" type parameters? The idea would be to use disjuntive type inference whenever the declared bound is a checked exception type. This is not strictly backward compatible, but it's unlikely to break real existing code. We probably can't get rid of "throws" in the type argument, however, due to syntactic ambiguity.

  3. Disallow @Shared on old-style loop index variables

  4. Handle interfaces like Comparator that define more than one method, all but one of which will be implemented by a method inherited from Object. The definition of "interface with a single method" should count only methods that would not be implemented by a method in Object and should count multiple methods as one if implementing one of them would implement them all. Mainly, this requires a more precise specification of what it means for an interface to have only a single abstract method.

  5. Specify mapping from function types to interfaces: names, parameters, etc. We should fully specify the mapping from function types to system-generated interfaces precisely.

  6. Type inference. The rules for type inference need to be augmented to accomodate the inference of exception type parameters. Similarly, the subtype relationships used by the closure conversion should be reflected as well.

  7. Elided exception type parameters to help retrofit exception transparency. Perhaps make elided exception type parameters mean the bound. This enables retrofitting existing generic interfaces that don't have a type parameter for the exception, such as java.util.concurrent.Callable, by adding a new generic exception parameter.

  8. How are class literals for function types formed? Is it #void().class ? If so, how does it work if object types are erased? Is it #?(?).class ?

  9. The system class loader should dynamically generate function type interfaces. The interfaces corresponding to function types should be generated on demand by the bootstrap class loader, so they can be shared among all user code. For the prototype, we may have javac generate these interfaces so prototype-generated code can run on stock (JDK5-6) VMs.

  10. Must the evaluation of a lambda expression produce a fresh object each time? Hopefully not. If a lambda captures no variables from an enclosing scope, for example, it can be allocated statically. Similarly, in other situations a lambda could be moved out of an inner loop if it doesn't capture any variables declared inside the loop. It would therefore be best if the specification promises nothing about the reference identity of the result of a lambda expression, so such optimizations can be done by the compiler.

As far as I understand 2., 6. and 7. aren't a problem in Scala, because Scala doesn't use Checked Exceptions as some sort of "Shadow type-system" like Java.

What about the rest?

解决方案

1) Can Method Handles be used for Function Types?

Scala targets JDK 5 and 6 which don't have method handles, so it hasn't tried to deal with that issue yet.

2) Can we get rid of the explicit declaration of "throws" type parameters?

Scala doesn't have checked exceptions.

3) Disallow @Shared on old-style loop index variables.

Scala doesn't have loop index variables. Still, the same idea can be expressed with a certain kind of while loop . Scala's semantics are pretty standard here. Symbols bindings are captured and if the symbol happens to map to a mutable reference cell then on your own head be it.

4) Handle interfaces like Comparator that define more than one method all but one of which come from Object

Scala users tend to use functions (or implicit functions) to coerce functions of the right type to an interface. e.g.

[implicit] def toComparator[A](f : (A, A) => Int) = new Comparator[A] { 
    def compare(x : A, y : A) = f(x, y) 
}

5) Specify mapping from function types to interfaces:

Scala's standard library includes FuncitonN traits for 0 <= N <= 22 and the spec says that function literals create instances of those traits

6) Type inference. The rules for type inference need to be augmented to accomodate the inference of exception type parameters.

Since Scala doesn't have checked exceptions it can punt on this whole issue

7) Elided exception type parameters to help retrofit exception transparency.

Same deal, no checked exceptions.

8) How are class literals for function types formed? Is it #void().class ? If so, how does it work if object types are erased? Is it #?(?).class ?

classOf[A => B] //or, equivalently, 
classOf[Function1[A,B]]

Type erasure is type erasure. The above literals produce scala.lang.Function1 regardless of the choice for A and B. If you prefer, you can write

classOf[ _ => _ ] // or
classOf[Function1[ _,_ ]]

9) The system class loader should dynamically generate function type interfaces.

Scala arbitrarily limits the number of arguments to be at most 22 so that it doesn't have to generate the FunctionN classes dynamically.

10) Must the evaluation of a lambda expression produce a fresh object each time?

The Scala specification does not say that it must. But as of 2.8.1 the the compiler does not optimizes the case where a lambda does not capture anything from its environment. I haven't tested with 2.9.0 yet.

这篇关于在Java中关闭Scala vs Closures的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆