On the eve of Sun's release of Java SE 6, Artima spoke with Coward about the future of dynamic language support on the JVM, about a new bytecode,
invokedynamic, explicitly designed to support dynamic languages, about hot-swapping—the ability to change or add a method to a class at runtime—and about the goal of turning the JVM into an ideal target for dynamic language implementation.
Frank Sommers: One of the most interesting features of Java SE 6 is support for dynamic languages. Could you give us an overview of what is available in today's Java SE release, and what additional dynamic language support are you planning?
Danny Coward: We noticed over the last couple of years that the Java developer community—unlike the .NET developer community—was starting to experiment with dynamic languages. Dynamic languages are increasingly becoming part of many developers' daily work with Java applications, and are often used for prototyping, for places where you want to put something rapidly together. People have been using dynamic languages to glue those parts of a larger [Java] application together that need to evolve quickly.
With the framework for scripting engines, developers can plug in their own interpreter engines as well. We managed to collect together more than twenty dynamic language engines at the java.net scripting project, scripting.dev.java.net. That's stage one for scripting language support in Java, and we delivered on that today.
JSR 292, Supporting Dynamically Typed Languages on the Java Platform, is the logical follow-on. Java is a statically typed language. The bytecode in Java expects certain information about what a return type is, and what the parameter types are for a method invocation.
When developers write interpreter engines for dynamically typed languages, they have to invent a lot of synthetic Java types to be able to fill in what's needed by the Java bytecode for method invocations. That makes those interpreters brittle: if someone changes the code, it's difficult to have to go in and reinvent all those synthetic types. Equally important, it slows down the performance. Interestingly, the Java virtual machine doesn't require to know statically what those types are, only the bytecode requires that.
JSR 292 is going to provide an additional bytecode that we will probably call
invokedynamic. This provides an instruction to the JVM to make a method invocation, but without the types of the return value and the method parameters to be known in the bytecode. It's quite a technical, bureaucratic reason, but the implication is that it will speed up those interpreter implementations on the JVM, and will also make them more robust.
Frank Sommers: Could you give us an example of how
invokedynamic will help a dynamic language interpreter perform faster?
Danny Coward: Suppose what you're doing is growing a collection by a certain size, and the return type [of that method] is
Collection. In JRuby, for example, that kind of method might be implemented without having a specifically typed return value. Developers may understand in their heads that what's going to be returned is a collection, but there is not a specific type of the return [value], because [Ruby] is not a statically typed language.
Creators of dynamic language engines are in the business of taking, say, Ruby code and turning that into Java bytecode. When today's JRuby engine tries to convert that method call into bytecode, it has to create a synthetic interface to represent the return type. That isn't an interface a developer creates, but is one purely created by the JRuby engine [so] that it can take that method invocation and [turn that into] the bytecode. And that was just the return type—the same holds true for method parameters and exceptions.
JSR 292 removes the need for that synthetic interface. Today, dynamic language interpreters must output the
methodinvoke bytecode, even when interpreting, say, a piece of Ruby code. Tomorrow, with JSR 292, they will be using the
invokedynamic version. It will streamline the engine implementations because a lot of today's engines are worrying about creating new synthetic types and doing lots of book-keeping: when a method is called in seven or eight different places, they have to re-use that synthetic type all over the place.
Interestingly, this is not a feature of the language, but a feature of the bytecode. Java developers won't ever knowingly use a feature of JSR 292—it's something that goes on under the covers. What's most fascinating about this additional bytecode is that it will be the first bytecode [in Java] that isn't used by the Java language. We're proposing to add this bytecode purely for languages like Ruby, Groovy, BeanShell, Python, and so on. We have high hopes that those languages will run more quickly on the JVM than they do today as a result.
Frank Sommers: Will this additional bytecode work on today's JVM's?
Danny Coward: The other part of JSR 292 is to investigate something called hot swapping. In many dynamic languages, methods can be changed, and even added to a class, at runtime. That was the bread and butter of Smalltalk programming. The idea is to be able to adapt classes at runtime.
JSR 292 just got started earlier this year, and we're not certain how this will work out yet. But it's part of the expert group's task, and this may also contribute to performance improvements in dynamic interpreters. This feature will probably require some re-working of the JVM, and the JVM will require some changes because of this. The expert group will also have to be careful about security concerns. We're certainly not going to open up any security holes in the platform.
Frank Sommers: You mentioned many advantages of dynamic languages. Do you see Java itself becoming a more dynamic language over time?
Danny Coward: It might be interesting to look at how we could evolve Java into a dynamic language, but a lot of the strength of Java—the robustness, the maintainability, the ease with which you can publish APIs to other people—are afforded by Java's static typing. That's something we wouldn't actually want to change. Instead, by making other languages run better on the JVM, there will be less of a need to change Java.
We still think that the Java language is the best language for long-lived, maintainable, shareable application code. For applications that enterprises are writing, that need to survive for a long time, and where parts of those applications are going to be shared—perhaps between different development teams, maybe even shared in the community—the static typing features of Java, the modularity we're working on, the package structure, all those things together add up to a language that helps create long-lived and robust applications.
Where we see the use of dynamic languages is in a bit of a different design center: in situations where at least parts of an applications evolve very rapidly. In those situations, it's less important to be able to share code with someone else, or perhaps to be able to read a piece of code six months later and understand what it does. Instead, it's more important to be able to evolve the code quickly, and perhaps throw together a demo or re-work the way widgets are wired on a Web form, for example.
That's why JSR 223 is important: we allow Java developers to program parts of their applications in a dynamic language, and then either evolve those parts of an application into Java over time, or keep writing the more robust, longer-lived parts of the application in Java, and the rest in a more dynamic language. We're living in a community where people have very different tastes over the languages they want to use. Why shouldn't they want to use Ruby as well as Java?
Equally important, the Java language has been around for ten or eleven years, and we've made remarkably few changes to the language. We are very aware that it's absolutely possible to keep adding new features to the Java language to satisfy every possible need in the community. But if we did that, we would end up with a very complicated language. We'd end up with something like C++, where I think they favored language features over simplicity.
Frank Sommers: To what extent do you consider the JVM to be an ideal target environment for implementors of dynamic languages? Do you see any limitations in the JVM that makes such language implementors' tasks hard?
Danny Coward: The bytecode is the main problem today, that you have to invent synthetic types. That's why JSR 292 is important.
Theoretically, of course, the JVM can host any language interpreter. Many things are possible, and theory is good, but practice is even better. The key is to make [dynamic] languages perform really screamingly fast on the JVM, and that's what we're trying to do.
So let me turn this question around, and ask that if you are a dynamic language designer or implementor, why would you not want to target the JVM as your primary implementation platform? We've spent eleven years pouring the output of some really smart people into a cross-platform, scalable runtime that's very widely deployed in the industry. Why wouldn't you target that if you were inventing a new dynamic scripting language? What runtime is better?
In the future, there is going to be a new language that's going to be really popular. The Java community, and Sun especially, is very interested in making sure that we can bring all the benefits of the JVM to whatever that new language may be.
JSR 223, Scripting for the Java Platform
JSR 292, Supporting Dynamically Typed Languages on the Java Platform
The Scripting Project Home Page, which lists the 20 scripting engines currently included in the project:
Frank Sommers is a Senior Editor with Artima Developer. He also serves as chief editor of the IEEE Technical Committee on Scalable Computing's newsletter, and is an elected member of the Jini Community's Technical Advisory Committee. Prior to joining Artima, Frank wrote the Jiniology and Web services columns for JavaWorld.