Clojure: a beginner’s notes

I started learning Clojure earlier this year because I had heard that it was simple and beautiful and that learning Lisp was a mind-expanding thing to do. In no particular order, here are some of my observations:

For context, my day job is as a Rails developer.

You can’t just muddle through

When learning other languages I’ve found that learning the syntax for methods, iteration etc is usually enough to be dangerous. Not so in Clojure, where you have to learn the concepts. Some things are extremely awkward if not impossible if you don’t have a clue about partial, zipmap, interleave, drop , union and other things which you might have merrily ignored in eg Ruby.

I am half-expecting enlightenment

Every time I sit down to write some Clojure I hope in a small way that I am about to have some sort of transcendental experience brought on by the elegance of it all. This hasn’t happened yet, but I have thought that things were quite cool.

I do not know if the things I thought were cool are the things that others consider to be elegant about Clojure. I wonder what those things are.

4Clojure is great

But even some of the problems marked Easy are hard. The solutions are often more or less mind-blowing. I am glad I ran through as many of these as I did before I tried to implement anything. I recommend following dzholev.

Please don’t make me use emacs

I’m a vim user. I installed vim-fireplace and vim-sexp, and things seem kind of ok. I can’t help but wonder what I’m missing out on from emacs. I am good at vim, but I find it fairly horrible to edit s-expressions in it, even with vim-surround.

The REPL is convenient

For example:

  1. Write function and use vim-fireplace to evaluate it in the REPL.
  2. Invoke function from REPL, revealing unexpected behaviour
  3. Change function and re-evaluate it.
  4. Press up in the REPL and run it again, yielding different results.

This is great! However,

The REPL is difficult and/or confusing

Your code might not have state, but the REPL does, and I find it difficult to manage. I’d run a test from Vim and I couldn’t be sure if the result was a pass or false positive, because I couldn’t be sure which version of the function I was testing I’d last evaluated. Super confusing!

You build programs bit by bit

My first Clojure program is a data model for a Rubik’s cube. My approach has been to roughly chop up the processing into functions, try to write them and unit test them, find they do too much (or too little), chop up again and repeat. I’ve ended up with a handful of well-tested low-level functions that operate on little parts of the cube (ie the mini-cubes) and a layer of hardly-tested higher-level functions that operate on whole sections (rows, columns etc) of the cube.

I haven’t tested those much because tests for big data structures are hard to fit on one page and in my head. Also, I have a reasonable amount of confidence that if I map over a function I have tested to death, I don’t need to worry about that working—as long as I got the syntax for that higher-level function right. I wonder if this is what functional programming feels like.

I like the feeling that if I can trust my little functions, the big functions will do the right thing.

The approach I’m taking after writing a bit of Clojure

If I have a choice between writing a function that operates on a set of things and a function that operates on an individual thing from that set, I’ll choose the latter because it is much easier to reuse.

Functions are either doers or gluers. Doers do things like filtering, transforming and updating. Gluers call ->mappartialapply etc to link doers together. Doers are words, gluers are sentences.

Functions that take params plus a data structure to work on like to take the data structure as their last argument, so they can be partially applied.

Running tests with lein test is not an option

lein is amazingly slow! On my laptop it takes over 30 seconds to load and about 10 ms to run the tests. The solution seems to be to run the tests from your editor (but then you contend with state in the REPL).

You will be writing SQL by hand

Coming from Rails, I was amazed to discover that Luminus, which is as far as I can tell the pre-eminent web framework for Clojure, expects you to write your SQL queries by hand. By hand!

Composition over… everything else

Luminus is not so much a framework as a collection of libraries that provide the bones of an application, and once it’s installed you’re on your own with regard to how you organise your code. It’s closer to express.js than any of the “proper” MVC frameworks. There is nothing wrong with this but it’s a bit daunting for a beginner, especially one who is a bit worried about code organisation and namespaces.

Namespaces

Coming from Ruby, I’m almost inclined to treat namespaces a like classes and group functions that operate on the same data structure in them. But I suspect I’m just being set in my object-orientated ways. Another idea is to group functions that do the same sort of thing (eg printing functions, transforming functions, filtering functions, etc), but I wonder if that will end up with large namespaces full of functions, which I’d then split up into groups, and end up with an explosion of subdirectories and small files. Maybe that isn’t so bad .

I haven’t found that requiring namespace A inside namespace B and then requiring namespace B in namespace C means namespace A is available in namespace C. I am probably missing something here.

Must you already appreciate mathematics to appreciate Clojure?

I am bit worried the famous simplicity of the language is not the kind of simplicity I consider to be simple.

I suppose I’ll find out.

Advertisements

3 thoughts on “Clojure: a beginner’s notes

  1. Hi,
    You might want to try emacs + evil-mode. I’ve used to be quite skeptical about Emacs (being VIM user), however I’ve tried evil-mode and I think Emacs + evil-mode is the best VIM.
    It takes some time to accommodate, but I really enjoy good parts of Emacs + VIM productivity.
    If you don’t want to spend time researching good plugins for you, you can try Spacemacs.

    Like

  2. You also might give spacemacs a shot, if you want to get serious with clojure. It comes with vim bindings by default (evil-mode) and is quite easy to configure, compared to a barebones emacs installation. I recently switched over to it, from vim, because the experience when working with clojure is just way better. And I was able to get productive immediately.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s