Pure Danger Tech


Learning Clojure #1: What’s up doc?

08 Feb 2010

This is the first in probably a long series of Clojure mini-blogs as I’m learning Clojure. I’ve only been using it in earnest for a week or so but I keep coming across little things I have to track down.

One thing that has been indispensable while learning Clojure is the ability to search for and view Clojure docs and look at the source for Clojure functions. At the REPL, this is extremely handy.

Let’s start with where these docs come from in the first place. Every function can have a doc description (similar to Javadoc) attached to it like so:

(defn rocks
    "Tell everyone that this thing rocks."
    (str "Alex says " thing " rocks."))

If you want to read the doc at the REPL, you can just ask for the function’s doc string:

user=> (doc rocks)
  Tell everyone that this thing rocks.

Then say later you remember you wanted to use this function but couldn’t remember exactly what you called it. You can search all of the known doc strings with the find-doc function:

user=> (find-doc "rocks")
  Tell everyone that this thing rocks.

So far I’ve found this to be indispensable while learning the language and the provided functions. If you want to go a step further you can coax Clojure into telling you the source for a function as well (since in Clojure code is data and data is code).

To use this functionality, you’ll need to import the repl-utils library:

user=> (use 'clojure.contrib.repl-utils)

user=> (source nil?)
(defn nil?
  "Returns true if x is nil, false otherwise."
  {:tag Boolean}
  [x] (identical? x nil))

You can find a bunch of other goodies in repl-utils as well. One that comes in very handy is “show”, which will dump all methods available for a variable:

user=> (show rocks)
===  public user$rocks__197  ===
[ 0] static const__0 : Var
[ 1] static applyToHelper : Object (IFn,ISeq)
[ 2] <init> ()
[ 3] applyTo : Object (ISeq)
....many more

You can also provide a regex to show to look more precisely for methods you might be interested in:

user=> (show 25 "^to")  
===  public final java.lang.Integer  ===
[20] static toBinaryString : String (int)
[21] static toHexString : String (int)
[22] static toOctalString : String (int)
[23] static toString : String (int)
[24] static toString : String (int,int)
[43] toString : String ()