Why did the split and join position argument in clojure.string mix?

I wanted to do this:

(-> string (str/split "\s") (modification-1) (modification-2) โ€ฆ (modification-n (str/join "\n")) 

But no, split accepts [s regex] , and join accepts [seperator coll] .

Is there any obvious reason for this insanity (read: what is this design decision)?

+6
source share
4 answers

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,

+8
source

You can use a partial function to correct the delimiter argument for str / join.

 (-> string (str/split #"\s") (modification-1) (modification-2) ;; (modification-n) ((partial str/join "\n"))) 
+2
source

I also regularly come across a similar (insignificant) alternating head.

 (-> string (str/split "\s") (modification-1) (modification-2) โ€ฆ (modification-n (#(str/join "\n" %))) 

and often create an anonymous function to coordinate the order. My guess is why some of the functions that you intend to use with the first -> stream, some for the last ->> stream ->> and for some streaming were not the purpose of the design, although this is just an assumption.

+2
source

There is nothing wrong with streaming streaming through another macro, for example:

 (-> string (str/split "\s") modification-1 modification-2 modification-n (->> (str/join "\n"))) 
0
source

Source: https://habr.com/ru/post/951730/


All Articles