Clojure’s
cond->
(and cond->>
) is a versatile macro. It isn’t a new macro, it
has been around since version 1.5, but I finally discovered and
started using it sometime last year. It isn’t a workhorse macro,
you won’t be using it everyday, but it comes in handy.
What is cond->
?
Let’s start by looking at the docstring.
1 2 3 4 5 6 |
|
So what does the docstring mean? Let’s break it down with an example.
1 2 3 |
|
In the above example 10
is the expr
mentioned in the docstring and
everything after it are the clauses
. Each clause is a pair made up
of a test and a form. In this example there is a single clause with
the value false
as the test the function inc
as the form. Since
the test evaluates to a false value the expression is not threaded
into the form. As a result the original expression, 10
, is returned.
Let’s look at an example with a truthy test.
1 2 3 |
|
Once again, 10
is the starting expression. The single clause has a
test that evaluates to true so the expression is threaded into the
first position of the form (- 2)
. The result is 8
and this is
returned.
Next is an example of a cond->
with multiple clauses. Explanations
are inline with the code.
1 2 3 4 5 6 7 8 9 10 |
|
If you understand the above example then you have a good grasp of
cond->
. But when is this functionality useful?
When do I use cond->?
Looking through the codebases I work on, I almost primarily see
cond->
being used with the initial expression being a hash-map. It
is being used in situations where we want to selectively
assoc
, update
, or dissoc
something from a map.
If cond->
did not exist you would accomplish those selective
modifications with code similar to below.
1 2 3 |
|
You can rewrite the above with cond->
.
1 2 |
|
If you’re not used to seeing cond->
the above transformation might
seem like a step backwards. I know it felt that way to me when I first
saw cond->
. Give yourself time to get familiar with it and you’ll be
glad you’re using it.
A meatier example of using cond->
is demonstrated below. Here we’re
manipulating data structures designed for use with
honeysql to generate SQL
statements. We start with a base-query
and selectively modify it
based on incoming parameters.
1 2 3 4 5 6 7 8 |
|
Hopefully this gives you a taste of cond->
. I’ve found it to be
quite useful. It has a place in every Clojure developer’s toolbox.