Virtual machines for all seasons

Generic VMs will allow developers to produce better-quality code with more flexibility than ever before

Looking at Peter Wayner's examination of possible futures for dynamic programming languages, I'm surprised that "better language technology" didn't rank higher on the list of evolutionary principles. All of the major interpreted languages have enjoyed a period of active development in recent years. Despite their humble origins, you can hardly refer to Perl, Python, or Ruby as "scripting languages" anymore.

I'm particularly interested in the growing convergence between dynamic languages and platforms like Java and .Net. Dynamic languages have lately been exploring such technologies as bytecodes and JIT (just-in-time) compilation, while the Java and .Net runtimes have been adding features to accommodate more dynamic programming styles. In fact, some engineers envision a time when the two technologies conflate completely.

The key to such a conflation will be to divorce the VMs from the syntactic details of specific languages. No more languages as platforms; imagine being able to program in the language of your choice and then choose from any of several different underlying engines to execute your code, depending upon the needs of your application. It could be the next major stage in the evolution of programming -- and it's happening now.

Write anything, run everywhere
Not surprisingly, perhaps, the first hints of this idea came from the dynamic-language side of the house. Though long delayed (some would say it has officially graduated to vaporware status), Perl 6 is expected to run on Parrot, a "generic" VM engine that will execute not just Perl code but also Python and potentially other dynamic languages as well.

Not long after Larry Wall and company began work on Perl 6, Microsoft introduced the .Net platform, and with it CLR (Common Language Runtime). Seen by many as Microsoft's answer to the JVM (Java Virtual Machine), the CLR has an advantage in that while the JVM was designed to run Java, the CLR supports a variety of languages.

The first beneficiaries of the CLR were traditional-style compiled languages, such as C++, C#, and Visual Basic. With some diligence, however, Jim Hugunin was able to implement a version of Python for the CLR, and other, similar projects would soon follow. More recently, Microsoft has announced the Dynamic Language Runtime, an effort to provide services on top of the CLR designed specifically to suit dynamic languages.

The Java camp is moving toward cross-language support, too. Projects like Jython and JRuby can create Java bytecode from Python or Ruby source code, respectively. In January of this year, Sun Microsystems announced a project called the Da Vinci Machine, a set of extensions to the JVM that will allow non-Java languages to run on the platform more efficiently. And at the first-ever JVM Language Summit, held in September, support for multiple languages on the JVM took center stage.

Stepping back from bare metal
It's easy to see why the idea of multiple languages running on a common VM is attractive if you look at the larger trends at work within the computing industry. As operating systems, code libraries, and frameworks have grown more sophisticated, there is less and less need for the "bare metal" power of C or assembly language in mainstream application development.

In fact, many developers would rather be freed from the hassles imposed by traditional systems programming languages. VM-based languages offer such features as automatic garbage collection, runtime bytecode verification, and security sandboxes -- all of which translate into peace of mind. Dynamic languages, on the other hand, mean efficient coding; their high-level syntax makes it easy to conceptualize applications and build prototypes rapidly. Put the two ideas together, make them interoperable, and you have a winning combination.

In the past, running code on dynamic language interpreters or VMs typically meant sacrificing performance. Modern JITs, however, are capable of outputting machine code that's almost as efficient as that produced from hand-coded C. Unless you're writing device drivers, games, or real-time applications, today there's little reason to choose a system-level compiled language for performance reasons alone.

The great advantage of a generic VM, as opposed to a language-specific one, is flexibility. By thinking in terms of targeting VMs, rather than language platforms, programmers are freed to choose the best tool for each job, secure in the knowledge that their code will enjoy the same reliability and stability at the execution core.

The OS as VM?
So where is all this going? It's early yet, but if this the trend toward multi-language support on VMs continues, I could see it panning out in one or two different ways.

First, the situation could stay more or less the same as it is now. A number of separate VMs could emerge, each capable of running a variety of languages, dynamic and otherwise. Developers could conceptualize and implement their applications in the languages of their choice, then choose the VM whose performance and capabilities best match the needs of their specific applications. Competition between the various players would push overall VM technology forward.

The other possibility would be for VM technology to go even more mainstream than it is now, and become more closely identified with the underlying operating system. One could argue that Microsoft is already doing this with .Net, by pushing for managed-code applications to be considered first-class citizens alongside traditional Win32 code. Why Sun never did the same with Solaris and Java is something of a mystery.

The first scenario is more likely; the second is perhaps more interesting. If every OS shipped with some form of generic VM, capable of executing code written in any number of languages, the last distinctions between native code and VM managed code would essentially disappear. Furthermore, application developers would be freed to concentrate on user-facing code, while OS and VM developers could collaborate on trickier low-level topics, such as better support for parallel processing.

This is, of course, a tall order. But the resulting improvements in overall application code quality would seem to make it a goal worth pursuing.