My disillusionment with Clojure and Lisps
Anders Hovmöller
67

Hello Anders, just a few points to consider regarding Clojure…

Re macros returning one thing — I think this is an interesting request but one that does not much consider the consequences. I’m not going to deep-dive on that, but suffice to say that I don’t think the tradeoffs are worth it. (A common workaround for this is to group multiple replacement expressions in a “do”, admittedly not something that works in every case.)

Re tooling, there are tons of tools. Full featured IDEs like IntelliJ/Cursive, Emacs CIDER, Eclipse/Counterclockwise. Whole tools written in Clojure itself like Nightcode or Light Table. Other integrations with Atom, Sublime, Vim, etc. New experimental ones like ProtoRepl. Interesting debugging add-ons like Sayid, logic-based refactoring tools like Kibit. Figwheel and Dirac in ClojureScript. I could go on — Clojure is awash in tooling these days, some of it leaps ahead of other languages. The notion that positional args is somehow holding back tooling seems implausible (most people would point first to dynamic typing I suspect). These tools *do* handle user written code and obscure libraries. You mention IntelliJ for Python which implies to me you haven’t tried the Cursive plugin for IntelliJ which has pretty amazing Clojure support. The new spec library for Clojure will enable the next level of data to boost these tools further as well.

I think your points about macros being languages are important — they definitely are and it’s important to remember that. That’s exactly why Clojure has developed a culture of using macros in ways that minimize that problem. Some of the most successful uses of macros are where the domain is described with basic Clojure data (maps and vectors, etc), manipulated with functions, and then has a thin layer of macro sugar over the top (there are many talks about this). In general, the majority of the macros I see are either pretty simple or built on top of a solid substructure. For sure, creating a DSL for every aspect of your system is a problem, so…. don’t do that. Write a big macro DSL where it matters — when it’s the core of your problem and worth investing in writing, maintaining, and documenting it, and it lowers either the typing or complexity of what you’re doing by an order of magnitude.

It sounds to me like you’ve definitely learned some things from building a macro-heavy library. Many other Clojure devs have walked this path too. You can take that knowledge to make the second or third take better though (and the data/function/macro layer approach is one great technique). I’d love to see you stick around and take that next step. I think Clojure’s small set of immutable collections and wide library of transformation functions provide an amazing substrate for quickly building robust applications.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.