In trying to stay with the functional style, I am having difficulty understanding when I should prefer:
(-> [1 2 3] reverse last)
over:
(last (reverse [1 2 3]))
When I come across both styles in a project, I find that it breaks my flow since I have to switch between thinking about function compositions and thinking about intermediate value states.
Which should I use at what times?
I mostly avoid using
->for one-argument functions; it’s a lot more useful when you have multiple-argument functions, because it lets you keep each function next to its “extra args”, without the focus object obscuring it.But also, you don’t have to choose one or the other extreme: one of my favorite things about
->is that it allows you to write the functions in any order at all, and you can use this freedom to write the code in whatever way you think is most readable. For example, perhaps you want to emphasize that you’re taking the last of a collection, and in context the fact that it’s reversed first is uninteresting:Or maybe reversing is important, and last is boring:
As an aside, note that I wrote
(last)and(reverse)here rather than justlastandreverseeven though the->macro implicitly inserts parentheses for you if you leave them out. This was on purpose: although it’s not a terribly popular style, I think it’s a good idea to always use parentheses in the forms given to->. There are several reasons for this:(-> (blah) (fn [x] (+ 1 (* x 5))))expands weirdly, because you are used to thinking that->takes a form rather than a function.It looks more regular in a multi-line
->with some unary functions and other multi-argument functions. For example:Isn’t it gross to have those two things in the middle offset, looking different from everything else?
The only argument I have ever seen for omitting the
()s is that it saves two characters of typing, which is not an argument at all.