recorrer da captura

A função recorrente de Clojure só pode ocorrer na posição da cauda. No entanto, isso não funciona diretamente ao usar um loop / recur para repetir uma operação possivelmente com falha.

Nesse caso, envolva a operação em uma conversão e retorne o valor em uma tupla de [exceção de resultado], onde o resultado ou a exceção é definido (que é XOR). Então, um simples ‘se’ pode ser usado para determinar se um resultado é retornado ou se outra tentativa deve ser feita.

Uma função que exige uma conversão e uma série de tentativas tem a seguinte aparência:

(defn try-loop [thunk tries]
(loop [n tries ex nil]
(if (zero? n)
(and ex (throw ex))
(let [[result exception] (try
[(thunk) nil]
(catch Throwable t
[nil t]))]
(if-not exception
result

(recur (dec n) (or ex exception)))))))

Comentários sobre isso:
– (if (zero? N) – testa se a contagem de novas tentativas terminou.
– (e ex (lance ex)) – apenas lance ex se não for nulo.
– (recorrente (dec n) (ou exceção ex) ) – o “(ou ex exceção)” é usado para manter a primeira exceção, em vez da última.