Lispийный способ читать пользовательский ввод с клавиатуры в Clojure?

Я пишу функцию для моей программы Clojure, которая читает ввод данных с клавиатуры. Если пользователь вводит неверный ввод, пользователь предупреждается, а затем запрашивается снова. При использовании процедурного стиля на языке, таком как Python, я бы сделал что-то вроде этого:

while 1:
    value = input("What is your decision?")
    if validated(value):
        break
    else:
        print "That is not valid."

Лучшее, что я могу найти в Clojure, это:

(loop [value (do
               (println "What is your decision?")
               (read-line))]
  (if (validated value)
    value
    (recur (do
             (println "That is not valid.")
             (println "What is your decision?")
             (read-line)))))

Это работает, но оно избыточно и выглядит многословным. Есть ли способ Lispy/Clojurey сделать это?

Ответ 1

(defn input []
   (println "What is your decision?")
   (if-let [v (valid? (read-line))]
      v
      (do
         (println "That is not valid")
         (recur)))

Ответ 2

Выполните компиляцию println/read-line в функцию get-line:

(defn get-input [prompt]
  (println prompt)
  (read-line))

(defn get-validated-input []
  (loop [input (get-input "What is your decision?")]
    (if (valid? input)
      value
      (recur (get-input "That is not valid.\nWhat is your decision?")))))

Это в основном то, что делает ваша версия Python; разница заключается в том, что get-input встроен для Python.