I have this curious demonstration of partials. Here is the code:
Start by declaring a vector and a partial. As expected, reduce and apply sums the integers on vector a
:
> (def a [1 2 3 4 5])
> (def p (partial + 10))
> (apply + a)
15
> (reduce + a)
15
Now, using apply on the partial p
and vector a
, I'm getting the sum of a
and the +10
from the partial, which makes sense:
> (apply p a)
25
Now, using (reduce)
makes no sense to me. Where is 55
coming from?
> (reduce p a)
55
The closest I can come up with is, (reduce)
version is adding 10 from the 1 index and ignoring the zero index before adding everything together:
> (+ (first a) (reduce + (map #(+ % 10) (rest a))))
55
I'm just curious if anyone knows what is happening here, exactly? I don't really know what answer I'm expecting with this, but I also don't understand what is happening either. I have no idea why I would get 55
as an answer.
The first thing to note is that +
is variadic: it can be called with zero, one, two, or more arguments. When you do (apply + a)
you are essentially calling +
with five arguments and getting the sum back (15
).
However, reduce
treats the function as strictly binary and calls it repeatedly, with the result of the previous call as the first argument of the next call. (reduce + a)
is (+ (+ (+ (+ 1 2) 3) 4) 5)
which also happens to be 15
.
So your partial
is also variadic and can be called with five arguments, as in the apply
call: (apply p a)
= (p 1 2 3 4 5)
= (+ 10 1 2 3 4 5)
so you get 25
.
The reduce
on p
is going to call it repeatedly as shown above, but this time the function adds 10
in each time: (reduce p a)
= (p (p (p (p 1 2) 3) 4) 5)
= (+ 10 (+ 10 (+ 10 (+ 10 1 2) 3) 4) 5)
so you get four 10
s and the 15
making 55
.
Another way of looking at Sean Corfield's fine answer:
Given
(def p (partial + 10))
then (p x y)
means (+ 10 x y)
, for any x
and y
.
So
(reduce p a)
means
(reduce (fn [x y] (+ 10 x y)) a)
... since the first argument to reduce
is a function of two arguments.
No initial value is supplied, so (first a)
is used as such, and the reduction is applied to (rest a)
, which has four elements.
a
get added in: the first as the initial value;
the others by reduction.10
gets added on in every cycle of the reduction: four times.So the final result is the same as
(+ (* 10 (dec (count a))) (reduce + a))
In this case, 55
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With