I wrote a function that tries to get a y/n (yes/no) answer from a user interactively. It tests if the answer is valid and if not, solicits the user again:
(defn get-valid-answer [question]
(println question)
(loop []
(let [ans (.trim (read-line))]
(if (#{"y" "n"} ans)
ans
(do (println "Please answer \"y\"[yes] or \"n\"[no] only!")
(recur) )))))
The above version with loop-recur does the job but I have nagging feeling that there must be a better (more functional) way to do this. I would prefer to have the read-line call made just once. Could anyone suggest an alternative version not using loop-recur in this scenario but possibly using some (Clojure builtin) macro instead?
Think of a small child asking the same question endlessly until it gets a satisfactory reply, then do the same thing in code. That is to say, take the first valid answer from an endless stream of questions.
Untested, but this should do the trick.
(defn ask []
(println "Please answer \"y\"[yes] or \"n\"[no]:")
(.trim (read-line)))
(defn get-valid-answer [question]
(println question)
(->> (repeatedly ask)
(filter #{"y" "n"})
(first)))
You could also define 'ask' in a let
binding, if two functions bothers you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With