Why I love Common Lisp and hate Java

“Common what?” is a common reply I get when I mention Common Lisp. Perhaps rightly so, since Common Lisp is not all that common these days.

Developed in the sixties, it is one of the oldest programming languages out there. In its heydays it was used mostly for Artificial Intelligence research at MIT, Stanford, Carnegie Mellon and the like, and therefore has a lingering association with AI. People not in AI shy away from Lisp. Common Lisp is a powerful and versatile programming language that can and should be used more often in other paradigms. It saddens me to see that Common Lisp does not even make the Top 25 most popular languages on Github.

A year and a half ago, a dear friend of mine send me this link. It changed the course of my life, although I shouldn’t extrapolate too far into the future. That was the first time I ever heard of Lisp and it hasn’t stopped enthralling me. After reading a couple of Paul Graham’s great essays, my curiosity forced me to spend the last year full-time learning and hacking away in Common Lisp. Aren’t those claims kind of bold? I had to find out. I am still new to Common Lisp but I love it enough to blog about it.

At university I was spoon-fed Java. Nobody likes to be spoon-fed. My degree (Computer Science & Economics) was about applying IT to business problems and I guess ubiquity was their guiding star. Not unwise to prepare not independent-thinking students for a job as a software engineer in a large corporation, but since the program was designed for students with an interest in applying IT applications to solve business problems, teaching Java killed it.. quite literally. Of course basic programming skills are essential to the curriculum, but why Java? It’s stressful!

About a half of my classmates dropped out after one year, because they said they didn’t like the programming part. That number rose in the subsequent years and they cancelled the program completely when I graduated. A sad ending for what I thought was a great program (except for the Java part).

Lispers like to pick on Java. It makes sense, because Common Lisp has everything that Java lacks. Common Lisp makes programming fun again. I can’t make direct comparisons with other languages, since I don’t know them well enough. But as far as I know, Lisp’s strengths are unique. You should look into it if you tend to spend 70% of your time in the test-debug-test cycle, 20% of your time writing unnecessary code and remain only 10% productive.

People say Common Lisp is difficult to learn, but I had more trouble learning Java. My first few spoons of Java were to memorize “public static void main(String args[])”, before I could start playing with some code. Oh and I forgot, you have to declare your class first. What is a class, and why so many lines, just to produce a simple “Hello World”? Programming sucks!

Compare

class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

with Common Lisp’s equivalent:

"Hello World"

That’s right. Just type that in the REPL and Common Lisp will return “Hello World”. As simple as it should be. REPL is the Read-Eval-Print loop that Java is missing. The REPL allows for interactive programming in a way that will keep you “wired in” as you hack and debug. You are in a constant conversation with your software. Compare talking on the phone versus texting when you’re trying to tell your friend about Common Lisp.

Beside the REPL, another impressive feat of Common Lisp is meta-programming. You can write software to write software. Say what? Yeah, that was my initial reaction too, but Common Lisp’s macro system allows you to write functions that return code snippets. It completely redefines the word. Or more accurately, re-redefines, since Lisp is much older than MS Office, which is what most people associate macros with, sadly.

Claims like these have been made all over the Internet. But for a skeptic like myself — who spent 4 months intensively practicing Tai-Chi in Beijing, just to confirm the existence of “qi” — I just had to try it for myself. “I cannot tell you what qi feels like, just like I cannot tell you what something tastes like. You have to try it for yourself,” my master told me.

When I was writing my thesis on a topic related to the Vehicle Routing Problem, I was forced to use Java. I was never given any choice — or the illusion of it. I spent 80% of my time on anything but developing my ideas into prototype software. I recently re-wrote the library in Common Lisp and released it open-source. I’ve been working on it just over a month, and I did so with a big smile. I couldn’t bother counting the number of lines, but to give you an idea, my Java source code was 500.4 kb versus 78.8 kb in Common Lisp. The Java source code is not disclosed — it’s too embarrassing.

For people in the Operations Research industry — broadly trained mathematicians with a knack for applying their skills in practice, who lack the training, patience and passion for the nitty-gritty of Computer Science — Common Lisp is the answer. Prototyping to test an idea or algorithm — to get quick results for your publication if you will — would not and should not have to incur the overhead of “researching”. Common Lisp allows you to focus on what OR people do best; designing that algorithm.

Just like I thought the all-you-can-eat sushi in Rotterdam was good; a complete paradigm shift when I got to Hong Kong.

Discussion on Hacker News and Reddit

Continue to Part II – code examples


For those interested to learn a little bit more, this is how I learned Lisp:

39 thoughts on “Why I love Common Lisp and hate Java

  1. I’ve just begun learning Java (because there seems to be great job opportunities for it in my country). I’ve read my fair share of criticisms about Java, but, as I wasn’t intending to learn it, didn’t give them much thought.

    So, first thing that annoyed me in my learning path: Only class constructors can be declared using no more than “public” and specifying no return value. If such an exception is allowed, why the hell do I have to type “public static void” when defining main, why not allow a shorter alternative!?

    If there’s a reason for this, I’d be glad to know.

  2. Before I forget, I tried Limewire a long time ago. The only thing I remember is that it is very inefficient. Therefore, I don’t consider it to be “impressive”, the way Maxima is.

    BTW, I have another addition to my list of impressive Lisp programs. It is the SBCL compiler. It is very fast, interactive, and I can use many friendly languages on top of it: Python, Fortran, Maxima, Java Script, Java Learner, Interactive Algol, etc. There are also text editors, Internet Applications, etc. Everything becomes interactive and fast on top of SBCL.

  3. I am curious about the so called Java success. I can list half a dozen Lisp based programs I use quite often. For instance, I could not survive professionally without Maxima. I use text editors with Lisp scripts, like Climacs, Emacs, and the Racket editor. I like a few games people say that are written in Lisp. I also use Orbitz to choose hotels, buy tickets, etc. I am a heavy user of the Common pdf generator, that the vendor claims that is written in Common Lisp. My Linux (Zorin OS) has many scripts in Python, that are very slow. Therefore, I have a Python compiler written in Common Lisp that improves things a little. I also use BioBike, and a Common Lisp version of Flymake (that I use to write Latex documents). All these Lisp programs are very good, better than the competition.

    I cannot remember a single Java program that I use. Is there a popular game written in Java? Or an internet site like Orbitz, or BioBike? I examined a few games for mobile devices in Java, but I think that they are quite primitive. They didn’t impress me, the way Maxima does.

    A program that I think is quite good is Calibre. Is it written in Java? To make a long story short, I would like you people to point out something written in Java that is as impressive as Maxima, Emacs, Biobike or Orbitz. BTW, I don’t think Eclipse is impressive at all. I would never switch from Emacs to Eclipse.

    • Yes, lots of popular websites are written in Java, like LinkedIn, Ebay, Twitter, Last.fm, and many of Google’s services. Your beloved Orbitz also uses Java, in addition to Lisp. Minecraft is a popular game that was written in Java.

      Your view of the software world seems rather biased. The computing done by average people does not usually consist of 3 text editors, a compiler for their Linux Python boot scripts, a PDF generation library, and a Flymake clone for LaTeX.

  4. LISP is great to author programs in and exactly ungreat when you’re trying to understand what someone else has authored. All the modern static analysis tools which make comprehending large, other-authored code bases at all possible don’t work with LISP since it’s neither strongly typed nor a compiled language.

    As it turns out, understanding other-authored code is more important than it first appears when you’re writing blocks world or some other toy problem in LISP. This is doubly true when that other person was actually yourself, five months prior.

    My first programming language was LISP. I had to get used to Java. Writing code in LISP is like playing with clay- anything can become anything at any time, just reform it and viola, it’s something else entirely. It truly is a lot of fun in a way no other programming language is fun. Turns out, that kind of fun is short lived and in fact dies a violent death as soon as code comprehension seriously enters the picture. Code comprehension is the God we flip off at our own peril
    .

    • Lisp is easier to understand than most other languages, because it is higher level, just like C is easier to understand than assembly language. You don’t have to learn the enormous Java library they’re using to simulate macros (with XML, usually!), because you can just read the 5-line Lisp macro they wrote. You don’t have to dig through a big method, because the same functionality fits in a small function. If they were good Java programmers and following OAOO religiously then they certainly have a DSL in there, too, and your static analysis tools can’t trace those, either.

      You seem mistaken about the reasons for this. Lisp is compiled, or at least, any Lisp written in the past 30 years is. It’s not statically typed, true, but neither are Python/Ruby/Javascript/etc., and anyone who’s studied computer science knows this doesn’t prevent static analysis. The reason your tools don’t work on Lisp is simply lack of demand.

      Yes, code comprehension is king, and because of that, I’ll take a 5-line Lisp function over 50 lines of Java (or 20 lines of Java and 30 lines of XML) any day. The reason you need those static analysis tools is because you have so much code. I have yet to see any non-trivial Java program which is less than 10x bigger than the corresponding Lisp program.

    • awesome that you’ve found a unifying philosophy to life and the source of your passions.. fascinating how that same philosophy drives all three of your interests.. I’ve never thought of it that way..

      Here a little post on how I was exposed to ki/qi through Tai Chi — do you see a unifying theme there as well? 😉

  5. Pingback: Lisp: Links, News And Resources (2) « Angel ”Java” Lopez on Blog

  6. Could you explain your experience with Qi? I’d like to hear why you believe it exists, and why your belief definitely isn’t a result of immersing yourself in a situation where everyone around you believes and acts as though it exists for several months.

  7. LISP is by far the most beautiful and wonderful language in the whole world. Too bad there isn’t too much work for LISP programmers.

    By the way, in the example above, you forgot to mention that you needed to create/include I don’t know how many files in Java and to print a simple “Hello World”.

  8. I disagree with the the suggestion that the minimal program should be given as (print (format t “Hello World!~%”)). The issue is what is the minimum program that lets you start exploring the language. For an example of what is meant by exploring the language consider

    “Hello World!” => “Hello World!”

    (reverse “Hello World!”) => “!dlroW olleH”

    (sort “elbow” #’char “below”

    (sort “elbow” #’char> ) => “woleb”

    (defun reverse-function (f) (lambda(x y)(funcall f y x))) => REVERSE-FUNCTION

    (sort “elbow” (reverse-function #’char> )) => “below”

    The fact that one doesn’t have to mess about with a wrapper such as

    (print (format t “~A” (sort “elbow” (reverse-function #’char> ))))

    in order to see what happens is a genuine advantage.

    • That is exactly the point, Alan, thanks for your comment — this kind of learning-by-exploration is what made learning (and using) CL such a fun experience for me.

      I think it does lower the threshold for those who want to understand about programming and play around a little, without getting their hands dirty, which is why I referred to my ex-classmates. To them, being able to quickly sort an “elbow” to get “below” and writing a function that will do that for them, would have been intellectually valuable and can be taught in 5 minutes, which might have peaked their interest to explore further.

      Meanwhile, a few weeks in Java 101, we started to get frustrated, because you do need to invest a little more in learning Java shenanigans, before you can straighten your elbow.

  9. The Common Lisp equivalent is actually (format t “Hello World~%”). Typing a string literal returns it as a value, but doesn’t send it to standard output, which is what the Java version does.

  10. Nice, but perhaps your CL example is a little disingenuous and should be:

    (print (format t “Hello World!~%”))

    “Hello World!” evaluates to itself and prints in a REPL, but that’s not always how you run Lisp programs.

    • You don’t need PRINT here. Passing T to FORMAT sends the string to standard output. In fact, (FORMAT T …) returns NIL, so calling PRINT on it gains you nothing at all.

  11. I think the root of the issue is that hackers really should be versed in a language of each type (OO, functional, scripting, etc…). While most languages are isomorphic of each other, some things are just easier in a certain language / way of thinking about the problem. I haven’t done anything serious in Common Lisp, but I did go out an buy “Land of Lisp” from amazon and I thought it was a fun and a good introduction to Lisp. And, it is published by No Starch Press, which is a great publisher!

  12. While I generally agree with you, I have to say that it is not fair to criticize Java that much – compared to, say, C++, Java is a true revelation! I mean, it does not have a reflection api as simple and powerful as CL, but at least it has one. It does not have lambda forms with closures, but it has interfaces which may have “final” parameters.

    • I understand your point, and I am not trying to criticize Java for the sake of it. Point of the article is to share my euphoric/transcending experiences I’ve had with CL. I come from a Java background myself, hoping that those skeptics, who are in the same position as I was a year ago (not to address those entrenched in their habits), would find it interesting and intellectually challenging to consider CL as an alternative.

      I also would like to point those who take offence to re-read the title of the post with an emphasis on the first-person aspect of it. I am not saying “CL is superior to Java”.

  13. Could you please exercise some moderation over the comments? I don’t want to be greeted by a profane, worthless insult the moment I read past the article. Also, the second comment is a vicious and ugly reaction that was very unpleasant even to look at.

    • good tip – I trusted people to be more humane and promote quick/smooth discussions without my constant approval of comments. If it happens again, I might just have to do that.

  14. ===
    Lispers like to pick on Java. It makes sense, because Common Lisp has everything that Java lacks.
    ===

    Except what it matters: an vibrant ecosystem, jobs, libraries of useful code, connectivity with external systems, those kinds of things.

    Plus you can run 2-3 different Lisp variants on top of the JVM, which makes the whole “Common Lisp” point moot.

    ===
    But as far as I know, Lisp’s strengths are unique. You should look into it if you tend to spend 70% of your time in the test-debug-test cycle, 20% of your time writing unnecessary code and remain only 10% productive.
    ===

    You forgot to mention spending 80% of your time writing code that exists as is in Java libraries but is not available as a CL module, or trying to hand-craft interfacing to some external system.

    Seriously, Lisp is not all it’s cranked up to be. Very few actual success stories (i.e stuff that people loves and uses) for such a hyped language family. Basically, Emacs, some in-app scripting (AutoCAD), and some internal systems. And the whole FAIL that was 70’s-80’s AI research.

    The things we like from Lisp (garbage collection, closures, reflexivity etc), most modern languages already have them. And the unique features of LISP (writing “DSL”s, data is code, macro system etc) are more trouble than they are worth in actual use. Haven’t seen any Lisp(ish) programmer team actually running circles around the 3242342342 other languages/environment out there. Graham touts ViaWeb as an example of Lisp’s competitive advantage, but being there first, at the right time, and doing some right moves was more of an advantage than the language used. Lots of other web ventures got quite huge in plain old Perl, if not PHP, and some even in hand-crafted C CGI, thank you very much.

    Btw, Paul Graham essays under serious consideration are mostly trite observations with some extravagant claims and bad style thrown in for good measure (read a few good essayists for comparison). Might want to read this:

    http://www.idlewords.com/2005/04/dabblers_and_blowhards.htm

    • Congratulations, you successfully managed to troll me, hope your happy. Angry lisp fan response follows, reader discretion is advised.

      First of all

      > Except what it matters: an vibrant ecosystem, jobs, libraries of useful code,
      > connectivity with external systems, those kinds of things.

      Citation needed. I happen to claim that most of that is available to lisp programmers in one form or another. Libraries? Check. Connectivity with external systems? FFIs and bindings for a lot of useful C libraries, as well as libraries that can be used for IPC like sockets, HTTP, message queues like 0mq and the like. Also check. If by vibrant ecosystem you mean a healthy community, well, we got that too. Many of the people using lisp manage to use it in their work, either by using lisp tools they write for themselves to help them in their work in other languages, or by having their own lisp business, consulting, or YES, even having a job as plain lisp programmers. Yes, there aren’t that many opportunities for using lisp, as there are for the currently fashionable java-ware, I feel there is enough opportunity for lispers. There are also at least two healthy commercial vendors who offer excellent products and have for years. That to me is a sign of a vibrant ecosystem!

      > You forgot to mention spending 80% of your time writing code that exists as is
      > in Java libraries but is not available as a CL module, or trying to hand-craft
      > interfacing to some external system.

      Citation needed. Again, how can you show this is true? Have you written real systems using lisp recently? Do you know enough people who have, who can confirm your experience?

      > Seriously, Lisp is not all it’s cranked up to be.

      Agreed, we need to have a realistic outlook on things, not a knee jerk reaction to too much hype!

      > Very few actual success stories (i.e stuff that people loves and uses) for such
      > a hyped language family.

      The two biggest commercial lisp vendors maintain lists of success stories:
      http://www.lispworks.com/success-stories/index.html
      http://www.franz.com/success/

      Keep in mind that these are products developed using lisp systems that cost thousands of dollars, so there’s probably not too many $0.99 Apps.

      > Basically, Emacs, some in-app scripting (AutoCAD), and some internal
      > systems.

      Why does a language have to have a portfolio of popular apps, in order for it to not be considered dead? As I’ve demonstrated, a lot of expensive and valuable systems have been developed in common lisp. Also, neither Emacs nor AutoCAD(AFAIK) use Common Lisp.

      >And the whole FAIL that was 70′s-80′s AI research.

      It was only a commercial and marketing fail, but a huge technical and scientific success. Read up on your CS history.

      > The things we like from Lisp (garbage collection, closures, reflexivity etc),
      > most modern languages already have them. And the unique features of
      > LISP (writing “DSL”s, data is code, macro system etc) are more trouble
      > than they are worth in actual use.

      As someone who is currently working on a python project, I would actually strangle a puppy if I could get my meta-programming super power back. I have a deadline, and i can’t afford to waste too much time trying to hack python into submission. Not having meta-programming is WAAAY more trouble if you have a deadline. Also Common Lisp has way more to offer other than macros. I miss CLOS every time i have to use these primitive object systems, the condition system is gorgeous and I miss it as well, having a FAST dynamically typed language with optional typing and type inference is a huge win in terms of performance. Interactive development is good only in Lisp and smalltalk, having a repl does not mean your language supports interactive development. Debugging in common lisp is a joy. Reader macros and named read tables are a joy, I love this language! A lot of these things I miss, a lot of them i miss in other lisps too!

      > Haven’t seen any Lisp(ish) programmer team actually running circles
      > around the 3242342342 other languages/environment out there.

      I have seen myself hack circles around myself using python and java. I agree, anecdotal evidence, but hey, I work with I can actually prove. This kind of thing is notoriously hard to measure with any accuracy and make sure you have scientific results not subject to any biases.

      > Graham touts ViaWeb as an example of Lisp’s competitive advantage, but
      > being there first, at the right time, and doing some right moves was more of
      > an advantage than the language used. Lots of other web ventures got
      > quite huge in plain old Perl, if not PHP, and some even in hand-crafted C
      > CGI, thank you very much.

      I agree to some extent. No business depends solely on its technology to succeed. PG over exaggerates something, news at 11 🙂

      ——-

      PLEASE stop retelling the old lisp myths, at least come up with new arguments. Non of my arguments are new, this discussion were having has happened thousands of times before, Its not the state of lisp libraries and jobs that’s depressing, it’s how persistent humans are to keep on repeating the same old misinformation decade after decade. If I teleport your discussion to 1988 I would have to change only a few details for it to fit right in with all the other lisp bile. Please quit it, unless you have ACTUAL lisp criticism you can back out with your real name under it so people can know who you are if you spread lies even if you believe them yourself.

    • “Except what it matters: an vibrant ecosystem, jobs, libraries of useful code, connectivity with external systems, those kinds of things.”

      I love this argument, because it points out just what critics of Lisp are so often thinking.

      You learn Java to get a job writing Java. The important thing about Java is not whether it is good or bad. The important thing about Java is that it’s popular. (The syntax might as well be COBOL.) Once you’ve invested in learning Java — and all its complexity, and all the libraries you need to make up for the language weaknesses — you can work in half the programming offices in the world. The only axis of value is perceived employability.

      To many people, it wouldn’t matter if you gave them a magic wand that could produce anything instantly. Microsoft and Google aren’t advertising job openings for people with magic wands, so such a thing would have no value.

      • I’ve been writing software for 30 years and I choose Java because I like it and it can be used to create elegant solutions (as can other languages).

        I picked up Java when I thought it would be fun to use to write a ray tracer in. Currently, I use it for game programming. I have very rarely used Java commercially.

  15. Nice blog post. CL is great for testing ideas. My original VRP work was done in CL and it proved many times to be an excellent “idea tester”. However, everyone that I work with never liked Lisp and so I was always forced, sooner or later, to move to C and/or Java. In spite of being more verbose languages, that speed myth notion and the parentheses were always a complain, to a point of irrationality. I could never really understand that…

  16. Thanks Pavel, I haven’t heard of racket before, will check that out. As for Clojure, I’ve scratched the surface, and their immutable datastructures philosophy – a good one in many ways – thwarts the natural OO approach to the VRP that I am working on currently. Perhaps something for another project, since I do see its advantage of basking in Java’s popularity.

  17. I love cl too, despite the competition from new functional languages like scala or haskell or newer dialects of lisp like clojure and racket(both of which you should check out btw, as people might ask you why you prefer one over the other). Because of Paul Graham’s essay on blub I don’t worry myself with competition from lesser languages, so long as I work on my own projects 😉

What say you?