Why Clojure? (2010)
They left out the part where Clojure DOES NOT implement tail-call optimization for mutually recursive functions. Without TCO, you can't fully leverage functional composition and immutable data structures without introducing some ugly hacks or relying on other language-level constructs offered by the implementation--that they can't be implemented in the language strongly suggests something about the limitations of the language.[1]<p>A great language that does optimize mutually recursive tail-calls, among many other elegant features: Lua!<p>... TCO, asymmetric stackful coroutines (90% as powerful as call/cc, but with zero calories), lexical closures, prototype-based object orientation, duck typing-based object orientation (among other possibilities), and a first-class C API that allows C code to work cleanly with coroutines, closures, the object system(s)....<p>Lua is truly multi-paradigm. The only downside is dynamic typing, though that's not always a liability and often an asset. Also, Lua has other interesting features, like lexical global namespace substitution using _ENV, that permit devising solutions to minimize some of the headaches of dynamic typing. And because Lua is so powerful in so many dimensions, yet so simple and tiny, writing unit and regression tests is often a breeze.<p>Once you add the canonical extension module LPeg into the mix (written by one of the Lua co-maintainers), Lua is about as formidable as they come. Only Perl 6 comes close to the ease of writing parsers with Lua+LPeg.<p>[1] The JVM will eventually add support for implementing TCO in Clojure and other languages, at which point many Clojure proponents will find religion in the power of TCO.