But there’s more to it than that. Libraries are just one benefit to building Clojure on top of Java, or, more accurately, on top of Java the platform.
Look around you, and you’ll see that 99% of all the software in the world runs on just three platforms:
- Java Virtual Machine
- .NET Common Language Runtime
Where did these platforms come from? Let’s see:
Notice something? All three were all developed by huge corporations.
Building a new platform isn’t just about writing the code. In fact, very little of it is about code. You need books, articles, conferences, workshops, and university courses. You need multinational corporations to trust their entire business to your platform. It takes millions of dollars and tens of thousands of hours of labor to create a new platform. Think of the massive ad campaigns Sun ran for Java. Can you do that? Of course not.
So when you’re designing a new language, you have to build on an existing platform. Most of the so-called “scripting” languages grew up on Unix, so they’re written in C. Now, Unix/C is a great platform, still going strong after 40 years. It provides powerful tools and standardized interfaces such as files, sockets, and pipes.
The problem is that each of the “scripting” languages has developed into its own mini-platform. Perl, Python, and Ruby each define their own set of data structures for fundamental types like strings, lists, and maps. The only “types” that Unix recognizes are text and binary. You can’t exchange data between two languages without serializing everything to some agreed-upon format. And you can’t do callbacks between languages below the level of a whole process.
The other problem with languages written in C is, well, C. Pointers are hard. Memory management is hard. I know from bitter experience that Ruby libraries can have segfaults or memory leaks. That just doesn’t happen in Java.
Clojure was created to leverage capabilities of Java-the-platform — garbage collection, dynamic code generation, JIT compilation, threads, locks — some of which are difficult to use effectively in Java-the-language. To implement Clojure in C, for example, you would first have to build your own platform with these features. That’s effectively what most Common Lisp implementations do, and they suffer because the Common Lisp world is too small to sustain its own platform.
The brilliant thing about Java-the-platform is that it allows many languages to coexist. I can mix code written in Java, Clojure, JRuby, Jython, etc. and it’s pretty easy, because they all implement the same fundamental interfaces like java.util.List and java.lang.Runnable. For example, right now I have Hadoop (Java code) calling Clojure code calling JRuby code. It all just works.
(The .NET CLR provides similar capabilities, and there is a Clojure CLR port.)