Question

Who can explain me this fact:

user> ((partial merge-with +) {:a 1} {:a 2})
{:a 3}
user> (apply (partial merge-with +) ({:a 1} {:a 2}))
nil

Why do I get nil in the second case? What is wrong with the second line?

Was it helpful?

Solution

The expression

({:a 1} {:a 2})

evaluates to nil. Maps in Clojure are functions which takes a key and returns the corresponding value. The expression

(let [f {:a 1}]
  (f {:a 2}))

which is equivalent to ({:a 1} {:a 2}) tries to lookup the key {:a 2} in the map {:a 1} and since there is no such key in the map nil is returned.

Going back to your original problem, all you have to do is to change the list ({:a 1} {:a 2}) to a vector [{:a 1} {:a 2}] and it will work as expected. Note also that you don't need partial in this particular case, (apply merge-with + [{:a 1} {:a 3}]) will work just fine.

OTHER TIPS

In the second case, when you ({:a 1} {:a 2}), as maps act as functions which get values from them, what you're doing is equivalent to (get {:a 1} {:a 2}) and, as {:a 2} is not a key in {:a 1}, you get nil. Then, aplying the function over nil gets nil.

What you have to do is either quote the list, such as not evaluate it as a function application

user=> (apply (partial merge-with +) '({:a 1} {:a 2}))
{:a 3}

or use a vector (which is more idiomatic in clojure)

user=> (apply (partial merge-with +) [{:a 1} {:a 2}])
{:a 3}

Juan Manuel

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top