First Steps with Clojure

So I’m starting to learn Clojure, using Stuart Halloway’s book Programming Clojure as a guide. It’s a steep learning curve for me as I’ve only ever done procedural and object-oriented programming, save for a brief dalliance with Scheme in a programming course I took in graduate school.

I get the basic concepts of functional programming (immutable data, functions without side effects, etc.) but am nowhere near the point where this functional mindset comes naturally to me. I still want to break things down into objects, with methods that carry out actions step-by-step.

One of the the things about Clojure that seems to be tripping me up a lot is the syntax surrounding the ns, use and require special forms. For example, one of the first references to use occurs on p. 19 of Programming Clojure, and it looks like this:

A bit later, on p. 38, he reintroduces use, but this time the example looks like this:

Now, I get that in the first example, he’s saying “only use the str-join function from the clojure.contrib.str-utils library,” while in the second example he’s using everything. What I don’t get is the differing syntax, using a quoted vector in the first example, and a quoted list in the second. It sort-of makes me think that this should work too:

but of course it doesn’t, and I get a mostly useless error message in the REPL. Now, if you’re an experienced Lisp, Scheme or Clojure programmer, you probably understand why this last example is wrong and you really don’t understand how I could possibly think that could be right, but I’m just not there yet. But I’m working on it!

Another thing that has hindered my progress a bit is the way that Clojure’s standard library and its API documentation are organized. Take the clojure.core library for example: it contains several hundred functions, and unless you already know the name of the function you’re looking for, tracking down just the right function for what you need is like looking for a needle in a haystack. For example, a little program I was playing with yesterday dealt with a list of maps, like so:

Now what I wanted was to convert this list of maps into a single map, where the names of the relation types were the keys and the values were the relation types themselves; i.e. a result like this:

After looking through the API documentation for clojure.core I decided there wasn’t any function that would perform this kind of transformation directly (or at least not that I could tell). I also determined (I think) that there’s only one function, hash-map, that will produce a map from its inputs; everything else seems to produce a list/sequence. So anyways, I ended up going with this approach:

and it works, but I’m looking at it and wondering, is this the best way to do this? Is there maybe a more efficient approach than first constructing a list of the type names, then interleaving those with the types to produce yet another list, and finally using hash-map to convert it into a map?

Having said all that, the challenge of learning this new (to me) approach to programming is fun, and I anticipate that it’s going to affect how I think about programs that I write in the languages that I already know well, like Ruby and Java. I’m also excited about finally having what feels like a more “practical” Lisp to play with, one that I can use with existing Java libraries that I work with every day.

Posted August 18th, 2010 in Clojure.

3 comments:

  1. Duwanis:

    I found that book less than ideal. It’s way too focused on the Java side of things, and not enough on the Clojure side of things… it’s almost a “this is how to use Clojure if you want to augment your Java code some” book.

    That said, I don’t think there’s really anything else out that’s complete. Manning has a couple of good-looking books that are in the MEAP, I think, but they’re just a few chapters here and there.

  2. Paul Stadig:

    Hey Lyle,
    Clojure is awesome! I took a job back in March at Sonian doing Clojure full-time. I only do nominal amounts of Ruby these days (if you remember we met at the Ruby Hoedown a few years ago).

    One way to find a function you need without knowing the name ahead of time is to use find-doc at the REPL. That will allow you to search within the docstrings of all the functions. (Obviously, you could also do something similar by pulling up the API docs in your browser and searching the page.)

    Hop on IRC into #clojure on freenode. The people are very friendly, and if you describe the type of thing you’re trying to do, then people will respond.

    There’s also clojuredocs.org which has some cool quick ref sheets (http://clojuredocs.org/quickref/varsonly/Clojure%20Core).

    Have fun! And feel free to contact me.

    Paul

  3. Lyle:

    Paul, thanks for the suggestions and information, but especially for the link to ClojureDocs: that is *exactly* what I was looking for. The problem (for me) right now with trying to search for a function (via (find-doc) or otherwise) is that I’m so unfamiliar with Clojure’s library that I don’t even know what to search for. On the other hand, if I think to myself, “I need to see what operations are available for maps,” I should be able to jump to that section in ClojureDocs and focus in pretty quickly.