repeatedly.rkt
#lang racket/base

(require racket/promise)

(define (repeatedly maximum err proc)
  (let loop ((tries 0))
    (let/ec
     okay
     (let/ec retry (call-with-values (λ () (proc retry)) okay))
     (if (< tries maximum)
       (loop (+ tries 1))
       (error (if (promise? err) (force err) err))))))

(define (test)
  (list
   (with-handlers
    ((exn:fail? (λ (e) "yay we failed
")))
    (repeatedly 10 "fail" (λ (retry) (display "beep
") (retry))))
   (repeatedly 10 "no problem" (λ (retry) "...BOOP
"))))

(provide repeatedly)