--
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?
Remember, recur isn't just for loop. It works with functions too.
I don't know the technical reason for disallowing recur from within a
catch/finally. A more restricted case came up recently in this
thread:
But that won't help with your case.
I suppose you could use a helper function that returns nil if there
was junk and then recur if you get nil back from the helper?
--
Michael Wood <esio...@gmail.com>
Generally, collect the information you need from the catch clause and
return it to a context where recur can be called if needed.
(defn prompt-for-int [prompt junk-allowed default]
(let [input (prompt-read prompt)
num (try (Integer/valueOf input)
(catch Exception _ :fail))]
(if (= num :fail)
(if junk-allowed
default
(recur prompt junk-allowed default))
num)))
Note that the above ugliness is caused at least in part by a mismatch
between the Java API and Clojure idioms. If 'Integer/valueOf' were a
Clojure function, I would expect nil to signal an error and any
Integer returned to be valid:
(defn parse-int [string]
(try (Integer. string) (catch Exception _)))
This would allow for a much cleaner definition of prompt-for-int:
(defn prompt-for-int [prompt junk-allowed default]
(or (parse-int (prompt-read prompt))
(if junk-allowed
default
(prompt-for-int prompt junk-allowed default))))
Or, since a default only makes sense if it might be returned:
(defn prompt-for-int
([prompt] (or (prompt-for-int prompt nil) (recur prompt)))
([prompt default] (or (parse-int (prompt-read prompt)) default)))
--Chouser