Closing Thoughts on Clojure

This is a video I meant to do months ago but just never got a chance to. There’s a billion other things I want to blog about. So I wanted to just wrap up my exploration into Clojure and move onto other stuff.

So in today’s video I reflect on my biggest gripe with Clojure and Lisp in general: readability. Lisp is powerful for sure but I don’t think that power is usually worth the sacrifice in readability and the ease with which other people can understand your code. So check it out below:

Clojure – Initial Impressions

Below are some of my thoughts about working in Clojure so far. I’m still really new to this language (and lisps in general) so I can definitely see myself changing my mind on some of these criticisms as I learn more. So far my overall impression is that compared to other functional languages, I’m not really getting anything extra with Clojure when it comes to expressiveness or maintainability.

1. When it comes to writing code, the parentheses are really easy to get used to.

I already have some experience with other functional languages, so I felt like I didn’t really have to change my thinking much to have it fit in with Clojure’s way of doing things. I get that the uniform syntax opens up the door for easier metaprogramming but for normal use I still prefer inline syntax to (having (to (nest (everything)))). But overall it doesn’t really seem to slow you down when you’re writing code.

2. When it comes to reading code, the parentheses make things harder to understand.

So here’s an example of some sample code I was writing (full code here):

Just in this simple function we’re nesting once at the letfn, then again at the let, then again at the if, then again at the other let, and then finally again at the doseq. Other languages would have similar levels of nesting for this kind of function but the difference is that you wouldn’t have to think about it as much. I feel like the parentheses are forcing me to think of the AST of the program and that’s distracting when I’m just trying to read and understand the code.

3. Clojure has good error messages.

There are a lot of different places where things can go wrong in Clojure. You have byte code compilation, you have macros expanding, you have Java interop, and you have an interactive environment that may or may not be in sync with the rest of your code. So I think it’s really impressive how helpful the error messages and stack traces have been so far. Even though Clojure’s not a widely used language doing Googling the error message usually helped my sort out my problems right away. I know that one of the design goals of Clojure to be as practical as possible and I think that’s something that really shines through in this case.

4. One-off command line apps are not a good fit for interactive development.

I feel like I haven’t really done a good job for getting a feel of coding with the REPL. The kind of test applications I’ve been making so far are all standalone utilities that you can compile ahead of time and call from the console. I think Clojure environments are just meant to stay running continuously (and starting them up can be really slow…). So I think I need to find myself a better test project work on.

One other thing related to this that I didn’t get a chance to look into yet is finding a good way to debug Clojure. Being able to inspect your current definitions is fine, but sometimes it’s still helpful to know what’s going on at every step of execution. I was relying on the “stick print lines everywhere” method of debugging and I feel like there’s probably a better way things than that.

5. I haven’t gotten to the good stuff yet.

There are two language features that I haven’t tried out yet: macros and mutlimethods. These are things that other (non-lisp) languages don’t have, so I’m looking forward to checking them out. I also haven’t done much with the asynchronous features either, so I also want to take a look at those. So far though from what I’ve seen, I feel like in terms of capability Clojure’s not really that distinguishable from the crop of functional languages that’s currently out there but maybe these other features will change my mind.

Getting up and running with Clojure in Windows

The recommended way to get Clojure installed is through Leiningen, this can be a bit frustrating in Windows since the installer is out of date, so here’s what you have to do to get started:

  1. Run the installer (make sure your JDK is up to date). If you try “lein repl” in a command line it will give you an error.
  2. Grab the latest lein.bat file.
  3. Update the LEIN_VERSION in the bat file to what you want to get. The default should be fine, but you can check here for a list of the latest releases.
  4. Drop the bat file into “C:\Users\<YourUserName>\.lein\bin” or wherever you installed Leiningen. Replace the old file.
  5. In the command line run “lein self-install” it should pull the standalone jar file.
  6. Now if you type “lein repl” into your command line the Clojure REPL should start up. And you’re good to go.

The next thing you should do is figure out which editor or IDE to use. There are solid Clojure plugins for Eclipse and IntelliJ but I found myself overwhelmed with tons of Java features that I wasn’t going to use. There are syntax highlighting plugins for Sublime and Atom but I wanted something a little bit more helpful and IDE-like so I settled on LightTable. LightTable’s really easy to get going with and it has good documentation, but if you really just want to jump into things, the least you need to do is:

  1. Create a new project with Leiningen: “lein new myproject” (make sure you’re in the directory you want to be in).
  2. Then in LightTable go to View -> Connections -> Add Connection -> Clojure. And then navigate to the project.clj file you just created with lein.
  3. After the project connects, you can open up the generated core.clj file and play around the instarepl, and that should be enough to get you started.