I've been thinking quite a bit about runtimes recently. It's an interesting topic in general, but I also have a more specific interest: I'm designing Fitz, a next-generation 2D graphics library, and I want this library to be as useful as possible. So I want to avoid gratuitous runtime incompatibility.
Bertrand Meyer's Polyglot Programming is a very insightful discussion of some of the consequences of Microsoft's Common Language Runtime (CLR). Here's a particularly interesting quote:
The language openness of .NET is a welcome relief after the years of incessant Java attempts at language hegemony. For far too long, the Sun camp has preached the One Language doctrine. The field of programming language design has a long, rich history, and there is no credible argument that the alpha and omega of programming, closing off any future evolution, was uttered in Silicon Valley in 1995. Microsoft's .NET breaks this lock.
Absolutely. What the CLR provides instead is a runtime hegemony. It seems to be a fairly high quality attempt, and is well on its way to achieving huge market share. The idea of a runtime hegemony provides almost all the advantages of a language hegemony, with the added advantage of providing a much easier migration path for components written in non-native languages to be assimilated into the runtime. Do note the echoes between Bertrand's discussion of libraries and Paul Graham's in Being Popular.
It remains to be seen, I believe, whether it's worth writing new CLR code in any language other than C#. It's a nice enough language, and you have the advantage of not having to worry about the language-to-runtime mapping Bertrand mentions towards the end of his essay. But other languages might turn out to provide compelling advantages over C# for this environment, and the CLR will, as Bertrand argues, support them.
There is now a flowering of thought, design, and implementation of runtimes on the free software side. This world is resistant to hegemony. Instead of one dominant runtime, we will see lots of different approaches. In the short term, this is a serious disadvantage compared with CLR, because it doesn't provide a good story for people (such as myself) who just want to write software. In the long term, I think, it could lead to much stronger working knowledge about how to knit together systems out of disparate components.
I'll list here a few selected projects I find interesting, with some comments focussed on runtime and integration.
- CPython. The CPython runtime is carefully layered on
top
of the C
runtime, supporting the highly dynamic Python, while
allowing full
access to the wealth of C libraries. In fact, CPython + C
can be seen
as an "aggregate language", actually a fairly compelling
platform.
Other language implementations, such as Ruby, fall into this
class as
well.
- Pyrex. Pyrex is essentially a hybrid language with
syntax and
semantics fairly similar to Python, but able to call C
directly. Thus,
we essentially have a 3-language aggregate, consisting of
CPython +
Pyrex + C.
- Lisp. Lisp is a mature language, with mature, high
quality
implementations. Most Lisp implementations provide a Foreign
Function
Interface (FFI), which is capable of directly calling C.
However, the
details of the FFI tend to differ from implementation to
implementation, so you can't really have a Lisp + C
aggregate, but
rather a family of CMUCL + C, AutoLisp + C, etc. See Design
Issues
for Foreign Function Interfaces for a much deeper
discussion. Also
note Arc, which could well become the most compelling Lisp
dialect.
- Parrot. See this interview
with Dan Sugalski for much more info on why Parrot is
interesting.
- Ruby/Python. This project attempts to knit Ruby and
Python
together. I'm including it largely because it illustrates
some
technical difficulties in integrating runtimes: the last
posted
version integrates Python 1.5 (which uses reference
counting) with
Ruby (which is fully gc'ed). It's relatively straightforward
to
integrate N runtimes when only one is gc'ed - it is the
master, and
all others are slaves. It's far harder to have more than
one, and
Ruby/Python seems not to have grappled with the problem yet.
- JVM (Java) + JNI. This is still a reasonable
approach,
but free
implementations are still not very good. They will get there
in time.
Note also Jython, which knits the Python language into the
JVM
runtime.
- Swig, an "interface language" for easy integration
of C
and
scripting languages. One of the most fascinating aspects of
Swig is
that a single interface can generate wrappers for many
different
scripting languages.
- Corba. Most people these days use Corba to
autogenerate
low
quality network protocols, layered on top of IIOP. However,
one of the
original goals of Corba was to facilitate integration
between a number
different languages. It is a mature standard, and fairly
well
implemented even in the free world, but is fairly painful in
practice.
- Mono and DotGNU, free clones of Microsoft's CLR.
These projects have widely varying goals and ambitions. Some will no doubt succeed, others fail. I expect our community to learn a lot in the process. And perhaps, some day, programmers can sit down and write code without facing difficult decisions about which runtimes to be compatible with, and which to be incompatible with.
Update: Stacking them up: a Comparison of Virtual Machines by John Gough. A well-written, technical comparison of JVM and CLR.
