I am new to Clojure and I am currently stuck with below code which throws a NullPointerException when I run it like this:
(mapset inc [1 1 2 2])
(defn mapset
[fn v]
(loop [[head & tail] v result-set (hash-set)]
(if (nil? head)
result-set)
(conj result-set (fn head))
(recur tail result-set)))
When I print the result-set in the if block it prints an empty set whereas I expect a set like this: #{2 3}
After trying to interpret the stacktrace I guess that the NullPointerException has something to do with the following line:
(conj result-set (fn head)).
The stacktrace and the fact that the resulting set is empty leads me to believe that the inc operation somehow gets called with nil as input.
I am glad about any explanation of why this error happens
The mentioned (shortend) stacktrace looks like this:
java.lang.NullPointerException
Numbers.java: 1013 clojure.lang.Numbers/ops
Numbers.java: 112 clojure.lang.Numbers/inc
core.clj: 908 clojure.core/inc
core.clj: 903 clojure.core/inc
REPL: 6 user/mapset
REPL: 1 user/mapset
I made some small changes:
(defn mapset [f v]
(loop [[head & tail] v
result-set (hash-set)]
(if (nil? head)
result-set
(let [res (f head)]
(recur tail (conj result-set res))))))
(defn x-1 []
(mapset inc [1 1 2 2]))
(x-1)
;;=> #{3 2}
So now mapset will call the function f on each of your inputs from v, then put the result of that call into the hash-set that was created at the outset.
The problem was in the control flow logic of your if statement. The flow of execution was continuing on after the if. Thus the function fn (which I renamed to f, rather than leave it as the name of a macro) was being called even when head was nil, which was not what you intended.
As originally coded the if (which would more clearly have been a when) was doing nothing useful. But once I realised you meant to have an if, but closed the paren off too early, then the answer slotted into place. Hence minor changes fixed the problem - your underlying logic was sound - and the amended function just worked.
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