Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closures in Scala vs Closures in Java

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?

like image 208
soc Avatar asked May 26 '11 16:05

soc


People also ask

What are closures in Scala?

A closure is a function, whose return value depends on the value of one or more variables declared outside this function. The following piece of code with anonymous function. val multiplier = (i:Int) => i * 10.

Are there closures in Java?

Java does not have closures. if you then do something like pass f to a function, scope is the scope of where it was defined.

Are closures and lambda the same?

A lambda expression is an anonymous function and can be defined as a parameter. The Closures are like code fragments or code blocks that can be used without being a method or a class. It means that Closures can access variables not defined in its parameter list and also assign it to a variable.

What is Closures in Java programming?

Closures are the inline-function valued expressions which means that they are the class functions with bounded variables. Closures can be passed to another function as a parameter. A closure gives us access to the outer function from an inner function.


1 Answers

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.

like image 112
James Iry Avatar answered Sep 28 '22 04:09

James Iry