conditional-statementsschemerestartmit-scheme

scheme: resuming a loop after a condition has been signaled


This program is using Scheme conditions and restarts to execute a procedure 10 times in a loop, and return the number of times the procedure did succeed.
Here the procedure throws an error each times n is a multiple of 3.
For some reason, the first error (n=3) is caught but the loop fails to resume with n=4:

(define (handle! thunk)
  (bind-condition-handler
   '() (lambda (condition)
         (display "resuming...")
         (invoke-restart (find-restart 'next)))
   thunk))

(let loop((n 1) (count 0))
  (display n)(display #\,)
  (if (> n 10) count
      (handle!
       (call/cc
        (lambda (cc)
          (with-restart
           'next "restart here"
           (lambda ()
             (cc (loop (1+ n) count)))
           #f
           (lambda ()
             (if (= 0 (modulo n 3))
                 (error n "is multiple of 3!")
                 (loop (1+ n) (1+ count))))))))))

I failed to find examples of conditions and restarts beyond the ones at the MIT Scheme Reference.


Solution

  • The solution is to move down the call/cc to the loop argument 'count' which is affected by the condition:

    (let loop((n 1) (count 0))
      (display n)(display #\,)
      (if (> n 10) count
          (handle!
           (lambda()
             (loop (1+ n)
                   (call/cc
                    (lambda (cc)
                      (with-restart
                       'next "restart here"
                       (lambda ()
                         (cc count))
                       #f
                       (lambda ()
                         (if (= 0 (modulo n 3))
                             (error n "is multiple of 3!"))
                         (1+ count))))))))))
    

    Runs correctly:

    1 ]=> 1,2,3,resuming...4,5,6,resuming...7,8,9,resuming...10,11,
    ;Value: 7