Brian Carper described a few days ago, how Clojure is better (for him) than Common Lisp (actually, SBCL). I managed to dig through ensuing flame war, but it seems like nobody in the flame war realized (or it wasn’t stressed enough) that original post is actually comparing apples to oranges, a serious language to a toy language.
A language, to be considered serious, needs to be self-sufficient, a serious language can’t be a mere parasite on some host language or environment, and its bus factor can’t be finite. That translates to just a couple of features:
- A serious language has to have a defining standard, it can’t be implementation-defined. A good standard bumps language’s bus factor to aleph null: after a nuclear catastrophe, archæologists of future generations should be able to re-implement the language on any hardware, including the Calculor;
- A serious language has to be self-hosting, or at least have some self-hosting implementations. Only then language stops being dependent on other languages.
Leaving aside other important traits (such as having multiple implementations, having a machine code compiler, extensibility, and so on), these two alone are necessary and sufficient for language to be serious; all programing languages not having these traits are just toys that can’t be guaranteed to last.
Toy languages may stay this way (as did Tcl and Perl, I think, and TeX is one-of-a-kind toy language which managed to grow enormously, staying implementation-defined and standardless). On the other hand, starting a toy language may be just a way to bootstrap a serious language without starting from gathering a commitee, and I think that’s what is currently happening to Python. I hope that will also happen to Clojure; I looked at it, and I liked what I saw (good concurrency support, decoupling polymorphism from data structures even more than in Common Lisp, a tiny bit more modern syntax, and it feels really well designed), however at the moment it is a toy language, feeding off Java, at very early stage of development.
Toy languages have short-term advantages (they are fast to create, usually simple, they leverage the host environment (libraries, operating system interface), they solve problem at hand quickly), and long-term disadvantages (lack of stability). Serious languages have short-term disadvantages (multitude of slightly differing implementations to choose from, every single one of which has its own differences and extensions to the standard; implementation/library compatibility matrix; standard features are set in stone and it may be tricky to work around them), and long-term advantages (stability, one can rely on a serious language to be there in one form or another in ten years).
I have nothing against toy languages: they do their job, and do it well. As a glue language, as a scripting language, as a solution to short-term problems, they’re good enough, and short-term advantages win over long-term disadvantages. Brian was trying to solve a short-term problem and, not surprisingly, toy language worked better. But: will the solution still work in ten, twenty years? Heck, will it work with next release of Clojure, or next release of JVM, or if Rich Hickey (Clojure author) gets hit by a bus? Brian didn’t need to answer these questions; do you?
When you get to choose a programming language, or any other tool, you may have some personal preferences, but don’t forget to ask yourself the single most important question: What is the problem you’re trying to solve? The answer to this question determines all further questions and answers.