clojure: как использовать recur в операторе if
Отказ от ответственности: я изучаю clojure.
Вот простой пример, который я пытаюсь запустить:
(ns ClojureTest.core)
(let [input (read-line)]
;if user input = "x"
(if (= "x" input)
;stop accepting input
(println "Exit")
;else output the input and continue accepting input
(
(println input)
(recur)
)
)
)
Теперь я получаю эту ошибку, которая, я думаю, имеет смысл, потому что я не знаком с синтаксисом:
Exception in thread "main" java.lang.UnsupportedOperationException: Can only recur from tail position, compiling:(ClojureTest/core.clj:8:7)
Как это исправить?
Дополнительные вопросы:
- Когда я нажимаю "запустить" в Eclipse (как я сделал бы с Java), я открываю не только консоль, но и это окно "REPL". Зачем это нужно и для чего это нужно?
- Когда я нажимаю "запустить", запуск приложения занимает довольно много секунд. Есть ли способ сделать это быстрее?
- Когда мне нужно отредактировать код и перезапустить приложение, я получаю это сообщение: "Выбор не может быть запущен, и недавние запуски отсутствуют". Что это такое и почему это не позволило мне перезапустить мой код? Если я подожду некоторое время, я смогу запустить его снова.
1 ответ
В данном конкретном случае вам не хватает do
в "остальном" предложении if
:
(do
(println input)
(recur))
Без do
, у тебя есть ((println input) (recur))
, который выглядит как вызов функции с возвращаемым значением (println input)
будучи функцией для вызова и (recur)
будучи выражением аргумента и так, а не в хвостовой позиции.
(Очевидно, (println input)
вернется nil
и попытка вызвать это как функцию будет бросать NullPointerException
, но это не имеет значения здесь - это будет ошибка времени выполнения, тогда как recur
проблема "не в хвосте" обнаруживается во время компиляции.)