clojure's -> (arrow) operator and optional operations
clojure, operators, syntax
Solution
You can do it with `cond->`, newly introduced in Clojure 1.5:
(cond-> x
true a
(> (a x) 2) b
true c)
Or, better,
(-> x
a
(cond-> (> (a x) 2) b)
c)
Meaning, "take `x`, thread it through `a`, take the result and thread it through `b` if `(> (a x) 2)` or else leave it unchanged, finally take what you've got and thread it through `c`".
In other words, `cond->` is like `->`, except instead of single forms to thread your expression through it takes test+form pairs, where the form is skipped if test is falsey and used for threading if test is truthy:
(cond-> x
test-1 form-1
test-2 form-2)
;; if test-1 is truthy and test-2 is falsey, output is as if from
(-> x test-1)
;; if it's the other way around, output is as if from
(-> x test-2)
;; if both tests are truthy:
(-> x test-1 test-2)
;; if both tests are falsey:
x
Problem
I've run in several situations where I want to do a chain of operations on an object with optional functions. "->" works great for sequences of commands on the same object (ex. (c (b (a x))) becomes (-> x a b c) ), except if some operations are optional. For example, suppose I wanted to do: ``` (c (if (> (a x) 2) (b (a x)) (a x) ) ) ``` Is there any way to do that in a clearer fashion using an operation like "->"?