11

As far as I understand, both Scala and Clojure have been designed as new languages that

  1. depend on the JVM, and
  2. easily integrate with Java code, in the sense that they allow to use Java classes inside Scala and Clojure code.

Starting with Java 8 (and maybe even more strongly with subsequent versions of Java), there will be changes in the semantics of the Java language.

I wanted to ask how these changes will impact the interoperability between Java and Scala / Clojure and what the consequences will be. For example, since lambdas in Java 8 are not objects (see e.g. here), Scala and Clojure might have to deal with Java values that are not objects. Would this be a problem?

I can think of the following scenarios:

  1. The Scala or Clojure language will be extended to adapt to the new Java semantics (to handle the new non-object values) and support interoperability with Java.
  2. The Scala or Clojure language will not be extended. This would only be possible if the new Java features like function values can be mapped to existing concepts. E.g., in Scala even a function is an object, so I guess Java functions would again be wrapped into some kind of objects when they become visible to Scala.
  3. The Scala or Clojure language will continue to support interoperability up to Java 6 or 7, without following latest Java's development. This would require that older versions of Java be still supported (at least by OpenJDK or another project), so that these languages can be based on a more conservative / stable branch of Java.

Summarizing: can we expect that the future development of Java will have an impact on languages like Scala and Clojure to maintain interoperability with Java? Is there some (link to) ongoing discussion on this topic already?

Note

I can imagine that Scala, Clojure, and other JVM-based languages won't have any major problems updating their implementation to newer versions of the JVM (and that new JVM features will make this implementation even easier). My question focuses on features of Java as a language and whether / how other JVM-language will be able to "see" / use these new features, not on whether JVM-based languages will run on the latest JVM's.

11
  • 6
    It is imprecise to say that Scala etc. depend on Java. They depend on JVM byte code. All the interoperability features deal with bytecode, not Java language source code, so whatever changes are made to Java itself are no threat. Only changes made to the JVM could affect these languages, and the JVM is extremely conservative - it basically never removes support for anything. In fact, most changes in the JVM nowadays are intended specifically for the newer dynamic languages. Commented Jan 8, 2013 at 9:54
  • @Kilian Foth: As far as I know a Scala String is a Java String. So Scala uses certain Java library classes. But I can change the formulation if you think it is too strong.
    – Giorgio
    Commented Jan 8, 2013 at 10:07
  • @Kilian Foth: I have removed the term depend because the focus of my question is rather on interoperability between Scala and Java resp. Clojure and Java.
    – Giorgio
    Commented Jan 8, 2013 at 10:18
  • @KilianFoth This should be an answer because it addresses the major concern of the question. The number one goal of any new Java release is backwards compatibility.
    – maple_shaft
    Commented Jan 8, 2013 at 12:25
  • 3
    @maple_shaft: I have corrected my question and removed the word "depend". As I have pointed out in another comment, my issue is not how Scala or Clojure depend on Java or JVM features, but how Scala / Clojure can "see" Java features. As far as I know they can see Java 6 features like classes, interfaces, objects, methods, primitive data types. This allows Scala / Clojure to use (call) Java 6 code. My question is, will these languages also "see" (and, therefore, be able to use) future Java language constructs or would this require extensions to the Scala / Clojure languages?
    – Giorgio
    Commented Jan 8, 2013 at 12:49

2 Answers 2

15

Actually Java 8 doesn't introduce much that will be detrimental to other JVM languages that interop with Java. The work done on Lambdas helped fix a number of small issues around invokedynamic, MethodHandles , MethodReferences etc - but apart from that it's carry on as normal. That said, there's a whole new bunch of APIs that the other JVM languages could potentially call into now. Which ones they'll use by default or not is up to them.

The largest change impacting interop actually came in with Java 7 - with the invokedynamic bytecode that allows dynamic/late binding calls within the JVM - something that was initially designed for the other languages on the JVM. It's since been very usefully adapted for Lamdbas, so as of Java 8, Java will actually start emitting these bytecodes.

Some languages (JRuby for example) are already heavily using invokedynamic, whilst others (Scala, Groovy et al) are still investigating its use or are in the early stages of patching it in. In theory it makes their dynamic calls almost as performant as existing Java invokestatic calls, as opposed to the myriad of slower workarounds they were forced to use in the past.

Java 9 will bring more challenges for JVM languages with project Jigsaw coming into the platform which will be the beginning of the end for traditionally class loading and classpaths for the JVM. The JVM language folks are pretty aware of this and I expect some sensible collaboration to take place.

13
  • 1
    But, as far as I know, a Scala closure is an object.
    – Giorgio
    Commented Jan 8, 2013 at 11:02
  • 1
    Yep. Scala only just recently dropped support for Java 1.5, it'll be a long time till they drop 1.6. Commented Jan 8, 2013 at 11:34
  • 1
    @Giorgio The language features of Java are inconsequential as most of those equate to bytecode tricks when compiled anyway. If we accept that the JVM will always be backwards compatible, even if new bytecodes are introduced, then Scala will be unaffected and can choose to take advantage of those new JVM features at their convenience.
    – maple_shaft
    Commented Jan 8, 2013 at 13:10
  • 1
    "The language features of Java are inconsequential as most of those equate to bytecode tricks when compiled anyway.": If another language wants to use a Java construct, it must be able to recognize the bytecode generated for that construct. If Java introduces a new constructs that maps to new bytecode, the host language should at least implement a new wrapper / interface to recognize and use the new bytecode. E.g. if a Java 8 lambda did not create an object but some new construct with new, specific bytecode for it, the host language must be adapted to recognize it.
    – Giorgio
    Commented Jan 10, 2013 at 8:43
  • 2
    @Giorgio: Sure, but no such changes are planned for the Java 8 platform. In fact, the JVMS was only extended twice in the entire history of the Java Platform, in 2003 and 2010, and the second time (introduction of the invokedynamic bytecode) was specifically to support languages other than Java; in fact, the Java 7 language does not support or use that bytecode. Commented Jan 10, 2013 at 15:07
2

Scala's about to be left behind when Java adds lambdas because Java lambdas get assigned a type according to the context they're used in, whereas Scala lambdas get assigned a type based on their arities, parameter types and return types, so e.g.,

executor.execute(() -> { System.out.println("hello world"); });

from Java 8 can be written in Scala as:

executor execute new Runnable {
    override def run() { println("hello world") }
}

unless you use/write some wrappers converting Scala's () => Unit to Runnable.

7
  • Thanks for the answer and also for addressing my question (+1). If I understand correctly, Scala will have to continue to use anonymous classes to instantiate interfaces in a context in which Java 8 will use lambdas (because Java 8 lambdas have a different semantics than Scala lambdas). Another point that is not clear to me is what will happen if a Java method returns a Java lambda. What happens if a Scala class calls that method? What will be the return type in Scala?
    – Giorgio
    Commented Jan 9, 2013 at 20:09
  • 1
    @Giorgio In Java 8 a lambda expression is a language-level shortcut to create an instance of interface that declares a single method and which is deferred by context. So when a Java 8 method returns a lambda, it actually returns an instance of interface which is declared as the method's return type. As of Scala 2.9.1, the return type is going to be simply an instance of some interface say (Runnable or Comparator) which you can not treat as a Scala lambda, unless you or future releases of Scala libary introduce an implicit conversion from that interface to Scala lambda type. Commented Jan 9, 2013 at 22:36
  • @SkyDan: Ok, so Scala will see Java lambdas as objects implementing some interface. This point was not clear to me: I thought Java would generate some bytecode that was different from that of an object. But it must be an object under the hood, otherwise it would not be recognized as the implementation of an interface. I think I got it now.
    – Giorgio
    Commented Jan 9, 2013 at 22:45
  • @Giorgio, also if you want to know more about lambda-related changes in Java 8 and forces that drive these changes, I recommend you to read this fascinating and detailed overview of the Lambda project. Commented Jan 9, 2013 at 22:55
  • @SkyDan: Reading it now. It seems to me that lambdas do represent objects (even though the type / interface is inferred from the context in which they are defined). So the information given at mail.openjdk.java.net/pipermail/lambda-dev/2011-August/… ("lambdas are not objects") is incorrect or, at least, misleading.
    – Giorgio
    Commented Jan 10, 2013 at 8:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.