Reputation: 896
I am creating an overloaded function that takes a list of numbers as a parameter (as well as a list of numbers and a single number in the overloaded signature). From this list the highest value must be found and returned. I am aware of the available "sort" method which automatically sorts the list for you but I am attempting to discover the highest value using recursion. Below is the code I am working with.
32 (defn my-max
33 ([list]
34 (if (empty? list)
35 -1
36 (my-max (pop list) (first list))) ; recursive call
37 )
38 ([list high]
39 (if (empty? list) ; base case
40 high)
41 (if (> (first list) high)
42 (my-max (pop list) (first list)))
43 (my-max (pop list) high))
44 )
45
46 (println (my-max '(1 2 3)))
As you can see, I have hard-coded a list containing 1, 2, and 3 for which 3 should be returned. when running the code I receive an error:
Exception in thread "main" java.lang.NullPointerException
at clojure.lang.Numbers.ops(Numbers.java:942)
at clojure.lang.Numbers.gt(Numbers.java:227)
at user$my_max.invoke(HelloWorld.clj:41)
at user$my_max.invoke(HelloWorld.clj:42)
at user$my_max.invoke(HelloWorld.clj:42)
at user$my_max.invoke(HelloWorld.clj:36)
at user$eval2.invoke(HelloWorld.clj:46)
at clojure.lang.Compiler.eval(Compiler.java:6619)
at clojure.lang.Compiler.load(Compiler.java:7064)
at clojure.lang.Compiler.loadFile(Compiler.java:7020)
at clojure.main$load_script.invoke(main.clj:294)
at clojure.main$script_opt.invoke(main.clj:356)
at clojure.main$main.doInvoke(main.clj:440)
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)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
This error occurs on the final recursive call where 3 has been "popped" from the list and is passed back to my-max as "high" the list is empty and:
(if (empty? list) ; line 39, base case
should evaluate true but is instead evaluating as false. Do you have any thoughts/solutions on this problem?
Upvotes: 1
Views: 1491
Reputation: 91557
the <
function can only compare numbers so a very straightforward approach is to use an or
to ensure they are numbers. Also the second and third if statements had the closing ) in the wrong spots.
user> (defn my-max
([list]
(if (empty? list)
-1
(my-max (pop list) (first list))))
([list high]
(if (empty? list) ; base case
high
(if (> (or (first list) 0) (or high 0))
(my-max (pop list) (first list))
(my-max (pop list) high)))))
#'user/my-max
user> (println (my-max '(1 2 3)))
3
nil
Upvotes: 4
Reputation: 13079
That statement (line 39-40) does nothing. No matter what it evaluates to (either high
or nil
), the value is not used. Then line 41 evaluates, and (first list)
is nil if your list is empty, hence the null pointer exception.
Upvotes: 6