As with Clojure 1.5, you can also use one of the new streaming macros.
clojure.core / โ
([name and form expr])
Macro
Binds the name to expr, evaluates the first form in the lexical context of this binding, then associates the name with this result, repeating for each a sequential form that returns the result of the last form.
This is a completely new design, so I'm not sure how to use the idioms, but I think something like this:
(as-> "test test test" s (str/split s #" ") (modification-1 s) (modification-2 s) ... (modification-n s) (str/join "\n" s))
Edit
As for why the position of the argument is different, I have nowhere to say, but I think Arthurโs proposal makes sense:
- Some functions explicitly work with collections (
map , reduce , etc.). They usually take the collection sequentially as their last argument, which means they work well with ->> - Some functions do not work with collections and usually take the most important argument (is this the thing?) As the first argument. For example, when using
/ we expect the numerator to be first. These functions work best with ->
The fact is that some functions are ambiguous. They can take a collection and produce one value, or take one value and create a collection. string\split is one example (apart from the additional confusion at the moment that a string can be considered as either a single value or a collection). Concatenation / reduction operations will also be performed - they will ruin your pipeline!
Consider, for example:
(->> (range 1 5) (map inc) (reduce +) ;; at this point we have a single value and might want to... (- 4) (/ 2)) ;; but we're threading in the last position ;; and unless we're very careful, we'll misread this arithmetic
In such cases, it seems to me that something like as-> really useful.
I think that in general, the usage guide ->> when working with collections and -> otherwise sounds - and it's just in these borderline / ambiguous cases, as-> can make the code a little neat, a little understandable,
source share