Hacker News new | ask | show | jobs
Ask HN: Have you felt that Clojure is a bad version of Common Lisp?
14 points by wizardofmysore 1716 days ago
I am not sure why I feel this way. Clojure on the outset looks like a perfectly fine coding language. However when I started using it I didn't feel that same elegance I would with Common Lisp.

I am unable to articulate why I feel this way. It's most likely because the Clojure code base I dealt with wasn't up to the mark.

Any views around the same? Have you felt this way?

4 comments

Not so much as a bad version of Common Lisp, but a half-baked Lisp. I am well aware that a response like this is bound to stir the opinions of other people about things like this, but I am also bound to express mine. There is not one correct response, and that everything can be considered subjective.

Clojure (on the JVM) is a lisp-y way to talk to the JVM and the rest of its ecosystem. Because it uses s-expressions, it allows for abstractions that are not possible otherwise. I have used Clojure myself in the past. It was fun.

However, there are still many things that are not polished in Clojure that are well-established in Common Lisp. The debugger of Common Lisp is one of the best out there. Its object system is also top class. Backtraces in Common Lisp allow you to get as much information as you can get from your program. Metaprogramming in Common Lisp is also out there in the top. The inverse, however, is not true. You need to have a PhD in JVM in order to read Clojure backtraces. You can easily create a program then dump it into a single executable with Common Lisp, not so much with Clojure. You want fast startup? Not with Clojure.

If you haven’t spent a significant amount of time with the different kind of lisps, it’s hard to make objective comparisons and judgement—everything that Clojure has would look cool and fancy.

I know some people who share the same sentiments that I have, who won’t reply to this thread. However, I’m a fool to even write this response.

They're not trying to be the same thing.

- Clojure has a unique take on state management backed up by unique value semantics. This has created an emergent data-oriented paradigm.

- It heavily favours functional programming and all of the built-in data structures are persistent.

- It is designed to be used and reused across different host environments (CLJC), not just the JVM.

- It bases its collections on a common, flexible abstraction (seq) and has introduced very useful data literals for maps, sets, vectors, regexes, etc.

- It eliminated a bunch of anachronisms like superfluous parens everywhere and car/cdr, while introducing useful syntax for destructuring.

- It's a Lisp-1 like Scheme.

Yes I felt the same. It always just disappointed me that it was built on top of the JVM, even though (or maybe because) I did write professional Java code for a few years. I can understand the decision and the reasoning behind it, but this made Clojure feel very limited, made it feel like it will never really "grow" as a language because it always had to stay within the Java realm.
JVM is a double edged sword when it comes to Clojure. JVM makes it possible to run on different environments, yet on the other hand it is constrained by the underlying semantics that JVM supports.

It is the latter aspect that has discouraged me from adopting Clojure for my projects.

Possible to run on different environments is totally not interesting IMHO. With docker almost anything can run anywhere.

The main advantage is that it can use 26 years of code written in Java + the standard Java library which already has a lot.

For myself I can only compare this to Rust. Where things like networking after 6 years of being stable, are finally starting to stabilize. While Clojure had this from its very start, because it ran on the JVM.

Docker was riding the x86 hegemony period but now with M1 Macs and ARM machines at major cloud providers, things are getting mixed up again. (But I agree this is a smaller thing than access to JVM libs)
When I tried Clojure I had to set up a "project structure" with files before I could run any code. With common lisp I can just start typing in a buffer in memory, and evaling right away. I can use common lisp as a quick little calculator. More freedom to use lisp as I see fit, not in someone else's vision of a "project".

The clojure repl took FOREVER to start up. Pocket programming is a no-go. SLIME starts up in a flash.

I don't have anything against the Clojure language itself. I'd say this is more of a credit to common lisp for getting so much so right in the language, runtimes, performance, and tooling. It's a unicorn.

You can "just start typing" in Clojure too. Eg:

  $ echo '(def foo 1)' > /tmp/foo.clj
  $ clj
  Clojure 1.10.x
  user=> (load-file "/tmp/foo.clj")
  #'user/foo
  user=> foo
  1