I've been reading OnLisp by Paul Graham. It's about becoming a better Lisp programmer. It's written for Common Lisp, but I have found quite a bit of it carries over into Clojure. One interesting code snippit I found in the book was on using let when two functions required the same value. Previously I would have done this through a def, like below:
(def step-by 7) (defn increment [x] (+ x step-by)) (defn decrement [x] (- x step-by))
Paul Graham instead approaches it like:
(let [step-by 7] (defn increment1 [x] (+ x step-by)) (defn decrement1 [x] (- x step-by)))
Obviously the example above is trivial, however there are times that shared immutable data is necessary. Database connection properties, connection URI information etc. I often have a small number of functions that need that sort of data. For these kinds of situations, I like this second approach. It more narrowly scopes the variable and I can't think of any drawbacks. I think this also highlights a difference in approach from imperative languages and functional languages in general. Paul (on page 30 of OnLisp) describes imperative language code structure as more "solid and blockish" whereas functional code tends to be more "fluid". The first example above fits the blockish imperative model where you define your variables and functions at the same level. This is exactly how I would go about it in Java. I've noticed that with the Clojure code I've been writing, and thinking back to code I've written in OCaml, it is definitely more fluid, a less rigid block structure. I've gone through about 6 chapters of the book thus far and am looking forward to reading through the chapters on macros.