For a while, I've been pretty clueless about using these two arrow macros (or functions). But I love how clean they make the block of code look. For a while, I was just copying them off of stack overflow or Clojure docs or even the Clojure slack channels. I hoped that if I kept at it, I'd eventually understand how they differed.
Last week, I had to append a string to a keyword but ensure the result was a keyword. So I originally wrote this:
user> (keyword (str (name :code) "_new"))
;; => :code_new
Then I thought, voila, this is just the stuff that the arrows make better! So I rewrote it like this:
user> (-> :code
(name)
(str "_new")
(keyword))
;; => :code_new
Wow, I got it right. But frankly, though, I cannot explain why it worked. Then I thought, that's cool. Here is a learnable moment. What if I did this instead?
user> (->> :code
(name)
(str "_new")
(keyword))
;; => :_newcode
And there, it became immediately apparent how the two arrows differed.
Maybe this is always apparent from the docs (and the comments). Or maybe if I had googled for an explanation, others would have explained this better too.
Honestly, though, learning like this tends to stick better for me. I hope this helps you out, in case that's how you landed here.