Clojure Гипотеза Коллатца NullPointerException

Я продолжаю получать NullPointerException для следующего кода, и я пытался и пытался отследить его, но безрезультатно. Я пытаюсь распечатать каждое число гипотезы Коллатца, которое он распечатывает, а затем выдает ошибку исключения нулевого указателя, и я не могу ее найти. Заранее спасибо!

      1 (ns collatz.core
       2   (:gen-class))
       3 
       4 
       5 (defn collatz [n]
       6   (
       7    (println n)
       8     (if (= n 1)
       9       (println "done")
      10       (if (odd? n)
      11        (collatz
      12          (+(* n 3) 1))
      13        (collatz (/ n 2))))))

  14 (defn -main []  (collatz 48))



Exception in thread "main" java.lang.NullPointerException, compiling:(/private/var/folders/yh/80f0k44s19lgzck9bgpq746w0000gn/T/form-init1027767069879550093.clj:1:125)
    at clojure.lang.Compiler.load(Compiler.java:7391)
    at clojure.lang.Compiler.loadFile(Compiler.java:7317)
    at clojure.main$load_script.invokeStatic(main.clj:275)
    at clojure.main$init_opt.invokeStatic(main.clj:277)
    at clojure.main$init_opt.invoke(main.clj:277)
    at clojure.main$initialize.invokeStatic(main.clj:308)
    at clojure.main$null_opt.invokeStatic(main.clj:342)
    at clojure.main$null_opt.invoke(main.clj:339)
    at clojure.main$main.invokeStatic(main.clj:421)
    at clojure.main$main.doInvoke(main.clj:384)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:383)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
    at collatz.core$collatz.invokeStatic(core.clj:6)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:11)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:11)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$collatz.invokeStatic(core.clj:13)
    at collatz.core$collatz.invoke(core.clj:5)
    at collatz.core$_main.invokeStatic(core.clj:14)
    at collatz.core$_main.invoke(core.clj:14)
    at clojure.lang.Var.invoke(Var.java:375)
    at user$eval5.invokeStatic(form-init1027767069879550093.clj:1)
    at user$eval5.invoke(form-init1027767069879550093.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6917)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    ... 14 more

person Jamie Ford    schedule 25.09.2016    source источник


Ответы (1)


У вас есть (println n) в позиции головы (строка 7), что означает, что вы пытаетесь вызвать значение функции, возвращаемое (println n). println всегда возвращает nil, поэтому вы получаете NullPointerException.

Минимальное изменение заключается в использовании блока do:

(defn collatz [n]
   (do
     (println n)
     (if (= n 1)
       (println "done")
       (if (odd? n)
         (collatz
          (+ (* n 3) 1))
         (collatz (/ n 2))))))

Хотя, честно говоря, в Clojure это выглядит неестественно. Более идиоматичным способом кодирования было бы создание последовательности вместо вывода элементов.

Кроме того, я сильно подозреваю, что вам не нужен gen-class. Если вам просто нужно запустить свою функцию, используйте REPL.

Редактировать: Как указано в комментариях, действительно минимальное изменение будет заключаться в удалении избыточных скобок, поскольку defnfn) включает неявный do

(def collatz [n]
  (println n)
  (if (= n 1)
    (println "done")
    (if (odd? n)
      (collatz
       (+ (* n 3) 1))
      (collatz (/ n 2)))))
person Yuri Steinschreiber    schedule 25.09.2016
comment
Минимальным изменением будет удаление ошибочной скобки после списка аргументов, поскольку defn имеет неявный do. - person Terje D.; 25.09.2016
comment
@TerjeD.- ты прав. Мне это так редко нужно (только для отладки распечаток), что я забыл об этом. - person Yuri Steinschreiber; 25.09.2016