Working on the problems on Project Euler to try to learn Clojure. I’m on problem 7.
I’m getting a nullpointer and I can’t work out what on earth I’ve done wrong.
;;By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can
;;see that the 6th prime is 13.
;;
;;What is the 10 001st prime number?
(defn isPrime [x]
(if-not (> x 2) false (loop [i 2]
(if (= i x)
true
(if (= (mod x i) 0) false (recur (inc i)) )
)
)
)
)
(loop [ x [2]
y 3 ]
(if (= (count x) 6)
(println (last x))
( if (isPrime y) ((let [x (conj x y)]) (println (str (last x)))) )
)
(if-not (= (count x) 10001) (recur x (inc y)) )
)
The error is with the ( if (isPrime y) ((let [x (conj x y)]) (println (str (last x)))) ), according to java.
Here’s the traceback..
gcoles@gcoles-pc:~/euler$ clj 7.clj
2
Exception in thread "main" java.lang.NullPointerException
at user$eval2.invoke(7.clj:21)
at clojure.lang.Compiler.eval(Compiler.java:6511)
at clojure.lang.Compiler.load(Compiler.java:6952)
at clojure.lang.Compiler.loadFile(Compiler.java:6912)
at clojure.main$load_script.invoke(main.clj:283)
at clojure.main$script_opt.invoke(main.clj:343)
at clojure.main$main.doInvoke(main.clj:427)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:415)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
The nullpointer actually doesn’t occur until the second time around the loop (Seen by putting a print after that let), so this confuses me a bit..
Anyone got any ideas on this?
Thanks.
The
letis of the following form:This will return the result of evaluating
body. In the code above, yourletform looks like this:Notice how there’s no body. Because of this, the
letform returnsnil. Since it’snil, the code you’re really envoking looks like this:Because of this, you’re effectively trying calling
nilas a function. This causes your null pointer exception. If, for example, you make your code:It will print out the last value of
x. However, it’s worth noting that this newx(the result of(conj x y)) is scoped only to theletstatement. If you actually want to use it elsewhere, you’ll have to, for example,recurwith it.