Clojure: Chaining Lamba Expressions that Act Like Partials

Really simple one. Say you have a chain like this:

(let [username (:username (?retrieve-value result))]
  (let [possible-error-message (text-is-empty username "Username")]
    (add-an-error-message result possible-error-message)))))

Pretty normal, and boring… and not super easy to read. Now this might happen only to someone who is rather new to Clojure (ME), but I figured I’d post it anyhow. Because I am that cool.

Using the -> macro (if you don’t know what that is, look at the Notes below), and lambda expressions (anonymous methods), it can be rewritten to remove a lot of the noise.

 (->
  (retrieve-value result)
  (#(:username %))
  (#(text-is-empty % "Username"))
  (#(add-an-error-message result %)))

That does the exact same thing as the original method, but cleans it up rather nicely. Though it still isn’t super mega ultra hyper readable…dx, it is still much easier to determine what is going on. Now the one thing needing to be noted is the extra () around the lambda expression. Because #(:username %) actually returns the method it creates, the second pair of () is used to call it with the value returned from (retrieve-value result). A little annoying, but really not that big of a deal.

Notes:

The -> macro

-> is used to chain methods together. Say I have two function signatures (PSEUDO CODE ALERT):

  f() :string
  g(string) : string

I could call them like this:

g(f())

With the -> operator I can do this:

f() -> g

As you can see the -> takes the result from “f”, and pushes it into “g”.

The # macro:

This is used to shorthand the normal lambda expression syntax.

(fn [a] (:username a))

Is the same as:

#(:username %)

Somewhat like the => operator in C# is used to replace the old anonymous method syntax from 2.0.