When programming Clojure, sometimes you need the equivalent of Common Lisp’s
prog1
macro. It’s like Clojure’s do
except that it returns the value of the
first form, not the last one.
You could depend on useful, which calls it returning
:
(defmacro returning
"Compute a return value, then execute other forms for side effects.
Like prog1 in common lisp, or a (do) that returns the first form."
[value & forms]
`(let [value# ~value]
~@forms
value#))
Of course, when you’re in a hurry, there’s no time for adding new dependencies.
There’s not even time to write your own inline version of the macro. Besides,
they say that you shouldn’t ever write your own macros. So what do you do? You
compose doto
and do
:
(doto x
(do
(y)
(z)))
;; returns x
Update (September 2021): Robert Levy pointed out to me that you can use
constantly
. Clever!
((constantly x)
(y)
(z))
But maybe instead of x
you have (a complicated form)
and you want to give
its result a name. Luckily there’s as->
.
(doto (a complicated form)
(as-> x
(do
(y x)
(z x))))
When you’re debugging a long ->
thread, a print function that returns the
printed value would be handy so you could insert it in the middle of the chain.
This is of course exactly what tools.trace is for. But again, who has
time for adding dependencies? Just use doto
.
(-> thing
do-something-1
do-something-2
(doto prn)
do-something-3)
By the way, the other day I wrote this macro that resembles cond->
:
(defmacro if-> [expr cond then else]
`(let [e# ~expr]
(if ~cond (-> e# ~then) (-> e# ~else))))
I used it with a builder object. The code looked something like this:
(-> (Builder.)
(.withSetting "password" "kissa2")
(if-> production-mode?
(.useProductionMode)
(.useTestingMode))
(.build))
Can somebody figure out how to do that nicely without writing a macro?