I’m going to make a bold proclamation. I’m not going to claim that Clojure will ever become the most popular language, but it will win in the next 15 years in a major way, because it is already one of the most interesting, and all signs show that it will continue to build momentum,. This is independent of what happens with the Java ecosystem; Clojure will be ready to go off of the JVM if it needs to do so. It is not in a hurry to make that change, but it that becomes necessary it will happen. Why am I so confident about Clojure? Partly, it’s the community. I started using Clojure in late 2008, and the language has improved by leaps and bounds, whereas many languages seem to have gone sideways over the past few years. That, however, isn’t the full story. There are a lot of good languages out there, and most remain in relative oblivion. What makes Clojure different? It’s not just one thing about it, because what I’ve realized about Clojure of late is that it’s not just a language. It’s a vision. Programming should be interactive, as beautiful as possible, modular, and it should generate assets that are easy to use and learn. The Clojure community gets that in a way that many language communities, within the enterprise, don’t.
On a fundamental level, this is different from the enterprise Java vision that has grown up over the past 18 years. The language itself (Java) isn’t so awful– it’s the C analogue of a very powerful garbage-collected virtual machine– but the culture that has grown up around it is conducive to gigantic programs, low interactivity, and manager-friendly conservatism. That doesn’t make it impossible to build good software– far from it– but it creates an environment that’s dissatisfying to the few people capable of writing good software. Clojure has gone the other way. Its build tools and frameworks (although not as fully featured as some in other languages) are simple, idiomatic to the language, and coherent with the vision. While the most “dangerous” feature of Clojure (macros) certainly does allow “cowboy coders” to run wild with ill-conceived DSLs, the truth is that one spends far less time contending with these parochial DSLs in a Clojure program than one does on a typical enterprise Java project; the latter tends to be full of ad-hoc DSLs built to overcome shortfalls in the language. Clojure, on the other hand, has little to be overcome in the language; one can extend it rather than making deeper alterations. Features are added to the language orthogonally, through libraries.
The reason why I say Clojure is a vision more than a language is that it strives to go into messy places that ivory-tower language inventors would avoid, while refusing to compromise on its core vision. It’s visually evident, when looking at a Clojure program, what aspects of the language are idiomatic and which are (usually temporary) tolerated compromises (e.g. the difference between using count or .length on a String). The language strives to remain attractive, but its purpose is to be a fully-fledged commercial language, and it will favor practicality when it’s prudent to do, and rejoin the prevailing aesthetic over time. Clojure is, in particular, designed to go beyond its most typical platform (Java). The reference implementation runs on the (typically server-side) JVM, but ClojureScript runs in the browser, and both dialects get core support. Also in accord with this expanding vision, Pedestal is one of many web frameworks that have been built for the language, and Incanter is bringing it into statistical computing. Then there’s Datomic, which applies Rich Hickey’s refined aesthetic and engineering senses to the database world. In Clojure, there’s a movement to restore a certain aesthetic integrity, modularity, and empowerment of the individual programmer that has, for a couple of dark decades, been lost in the enterprise.
Does Clojure have weaknesses? Of course. In 2008, the warts were evident, because the language was so new (for one thing, JVM interop was very painful). They’re less so now; one has to do a bit of work to find the issues. Yet it has very few fundamental weaknesses. The core language itself is very sound, and it’s only getting better as the vision is refined.
One argument made against it is its lack of a static type system. How damning is this? To be honest, I like static typing a lot, and used to be a die-hard defender of it. My view has softened a bit. My experiences with Scala– well-designed to its purpose, but solving a very difficult (and possibly impossible) problem, which is to unify the Haskell and Java worldviews– have convinced me that compile-time typing, strictly speaking, isn’t needed for most purposes. Interface integrity (type guarantees, contracts) is important, and Haskell and Clojure come loaded with different tool sets to guarantee such things. In the hard-line statically typed world, there’s a type system you get, implicitly, out of the box. It comes with the language, and can be extended in some powerful ways, but it has limits. There are some desired type-system features that require hacking the compiler or making fundamental “wizards only” alterations to the type system that, if done wrongly, can be dangerous. Type systems limit the kinds of programs one can write (and that’s a feature, because reasoning about arbitrary code is literally impossible). They provide automated reasoning about code that is better than the hand-rolled test suites found in 99% of web applications, for sure, but they also (perhaps surprisingly) limit some of the things one can do to reason about code. (If you make a type system too powerful, type-checking becomes undecidable and you’re back into the wild.) Clojure, on the other hand, certainly makes it possible to write sloppy code; however, it also makes it possible to prevent sloppy code in ways that are very difficult in its static counterparts. An enterprise Scala project, for example, is typically going to present the frustrations that come with components that live outside the language. Learning Scala isn’t that bad, but Maven and Spring and Hibernate? Ouch. In Clojure, most of the typically “external” needs are provided with idiomatic libraries that can be reasoned about within the language.
This underscores what I think is the biggest advantage to the dynamically typed world. Static typing is great when one is solving a known problem and requirements don’t change, but when quality and correctness are extremely important. While dynamic typing can theoretically be used to achieve the same level of correctness, I don’t think it’s always economical; it requires more error-handling code and there will performance costs that are only paid once on an executable (in compilation) in the static world. However, I think dynamic typing wins when the requirements are unknown or changing, rapid prototyping is essential, and (most relevantly) integration of new technologies, not always known from the outset, is mandatory. Interactivity and exploration become a core part of the development process at that point, and while every static language worth its salt has an interactive mode (“REPL”) it doesn’t have the same first-class-citizen feel. For example, Clojure’s REPL (which performs compilation of each statement) provides identical performance to what will be achieved in production, making it possible to time functions interactively.
On the static front, there’s nothing that stops the Clojure community and vision from confronting the typical commercial need set that is fulfilled by static typing, and it will. For research value, it will probably be steps behind Haskell on that front forever– Haskell’s a leader in that, and Clojure’s a leader in other things– and such features will always be optional, but I think it will meet most of the needs of typical programming. The shortcomings associated with dynamic languages are, in any case, more often cultural than intrinsic to the language, and Clojure’s culture is of extremely high quality, so I think there were always be enough awareness of those risks, and that the Clojure world will continue to produce technical assets of very high quality.
What makes Clojure– and I’m talking about the vision and community even more than the language– unique, in my mind, is that it takes a hard-line approach to both aesthetics and practicality, perhaps in recognition of the fact that those two need sets were never in opposition at all. The era in which one could “learn programming” in 6 months at age 22 and have lifelong job security are over. People constantly need to learn new things, just to survive, and that’s only feasible when newly-generated technical assets are coherent, attractive, and interactive. That, I think, is the biggest advantage of the Clojure approach to technology growth. Unlike the typical enterprise Java stack, it’s optimized for lifelong learners. That, above all, is why it will win.