Fork me on GitHub
#clojuredesign-podcast
<
2020-09-08
>
Stefan20:09:48

@neumann @nate This week I listened to the episode on partial . I didn’t quite get the part about partial apply in a thread, but besides that, it occurred to me that you can use partial in a thread-first to sneak in a function that expects the injected param last by partial applying all the args except the last one, so that in effect it becomes also the first. So something like:

(-> value
    (assoc ...)
    (partial map some-fn))
Is this something you would expect to see in production code? Is it “cheating” / confusing? Thanks!!!

nate20:09:01

the way I've accomplished that in the past is to just use the thread last macro. I forget who it was that I first heard that from, but it might be a Stuart Sierra tweet. For example:

(-> value
    (assoc ...)
    (->> (map some-fn)))

nate20:09:27

I remember liking it a lot when I first heard about that trick

nate20:09:28

but now, I generally don't mix -> with ->>, unless it's in exploratory fiddle code, because of the mental leap between "operating on an entity" and "operating on a list"

neumann20:09:31

@UGNFXV1FA Thanks for listening! I think you're missing a set of parens.

user=> (-> {:foo 1} (assoc :bar 2) ((partial map key)))
(:foo :bar)
I also concur with @nate that the ->> trick is easier for me to understand.

neumann20:09:04

@UGNFXV1FA Here's a use of partial apply too:

user=> (def max-list (partial apply max))
#'user/max-list
user=> (max-list [1 2 3 4 5])
5
user=> (max 1 2 3 4 5)
5

neumann20:09:53

Since max takes a variable number of parameters, you can use partial apply to create a function that expects a seq.

neumann20:09:33

And if you want to use max in threading, that's where the apply comes in:

(->> [{:name "Foo" :age 32} {:name "Bar" :age 64}]
     (map :age)
     (apply max))

Stefan20:09:24

Ok, got ya on the thread first/last, I understand what you mean and it sounds like a sensible thing not to mix them, so I’ll also go with that 🙂 As for the partial apply IIRC you explicitly mentioned using that as a last statement in a thread, but as also in your example above you don’t need partial in that case. Or am I misremembering and/or misunderstanding?