I love Lisp. That’s right, ‘inefficient’, ‘hard-to-understand’, very much out of the ‘mainstream’, and ‘parentheses-obsessed’ Lisp. Unashamedly love it to bits.
Lisp is, of course, the most powerful language available. That’s right, what looks like an odd syntax actually is a terse syntax that allows for a great deal of configurability. Where you probably are used to formulating a combination of keywords and punctuation to get your ideas across, in Lisp you directly code in what amounts to other languages’ compiler-generated parse trees. List programs are lists (of lists of lists…) and Lisp’s parse trees are lists too and generating parse trees in code therefore is very easy.
A program that generates and/or manipulates parse tree is effectively a program that (re-) writes programs. Now, this might seem like a gimmick that matters only in a game of geek trump stakes, but it actually opens up to a whole different style of programming. In Lisp you’re not limited to writing a program down towards the language, but you can also build the language up toward the program. If you’d ever think, “Gee, I wish I had this-or-that construct to make my problem go away”, you can go and write that construct to suit that particular problem. And inevitably, you will realize that using this new construct would simplify the design of another part of the program, and so on, and so on: language and program evolve together. You end up with a program that looks as if the language has been specifically designed for it. And having language and program fit one another optimally is what keeps the code as clear, small, and efficient as possible. Very few programming languages support this bottom-up design to the degree that Lisp does.
The phrase ‘design’ is there on purpose: to emphasize that this isn’t about writing the same program in a different order but that the resulting program is structured very, very differently. You end up with a larger language with more abstract (dare I say: more domain-specific?) constructs, and a smaller program written in it. And a smaller program doesn't have to be divided into so many components. Fewer components means the program is easier to read and modify and that there’re fewer connections between components, and thus less chance for errors. Small is beautiful and beauty is what's all about.
Of course, I haven’t ever (ever!) wielded Lisp on a paid job. And I reckon you haven’t either. Which means that you and I both missed out on something very important: the opportunities of server-side programming. When I started out programming, there wasn’t really much of a choice in the language to use for writing application programs. Back then, ‘applications’ generally meant writing software to run on desktop computers; and in desktop software there was a strong bias toward writing the application in the same language as the operating system. Fifteen years ago, in my world, applications were written in C/C++. Then, the Web happened and these things changed: in server-based applications it is far easier to get away with using the technology (language, OS, …) you like. Perl, PHP, Python, Ruby: they all got their place under the sun because people started using them on servers and not because people used them to do desktop stuff. Moving software onto servers means there’s just less pressure to use mainstream (or average, or middle-of-the-road) technologies.
If this sounds halfway reasonable, then only with 20/20 hindsight because for the past 7 years or so my diet has been building server-based applications using the very mainstream Java stack exclusively (and to a certain degree, inexcusably). I needed the Ruby on Rails wakeup call to ram the benefits of Lisp style home. Ruby of course too allows for the language to be extended in runtime from within. For Rails, the ‘base’ Ruby language has been raised in abstraction so that the problem of creating web apps effectively and the solution language fit one another better. Given rampant Rails’ success, the benefits (and joys!) that can be reaped from this are apparent to a significant amount of people. And it is the bottom-up design capabilities of Ruby that make it all possible. That’s why it’s called Ruby on Rails instead of Rails on Ruby (a fact that might have escaped the Trails project team).
Ruby and Groovy are no Lisp of course (Lisp’s macros really are something else), but they are effective enough in showcasing the fruits of Lisp style to make Java-the-language look, well, clunky. So clunky in fact that I could not bare programming Java without Eclipse’s editing and refactoring. I still do value Java-the-platform though, with its slew of great, proven and well-understood technologies for object/relational mapping (Hibernate, JPA), application configuration (Spring) and transactions (JTA) to name just an area’s. All of these technologies are of course perfectly addressable with Groovy and JRuby, which thus allows for superseding Java-the-language whilst leveraging Java-the-platform. What’s not to like, really?
Lisp. Ruby or Groovy… I’d say the future of server-side programming is funky!