Next: , Previous: , Up: restarts   [Index]


1.18.6 Associating restarts to conditions

Syntax: with-condition-restarts ?condition-form ?restarts-form ?body0 ?body

Evaluate body forms in a dynamic environment in which some restart objects are associated to a condition object; in some special case it is implicitly used by restart-case. If the body performs a normal return: the body return values become the return values of with-condition-restarts.

This is the sequence of operations:

  1. The expression ?condition-form is evaluated: its single return value must be a condition object, simple or compound.
  2. The expression ?restarts-form is evaluated: its single return value must be a list of restart objects, for example returned by find-restart.
  3. In the dynamic environment: every simple condition object returned by ?condition-form is associated to every restart object returned by ?restarts-form.
  4. The body is evaluated.

Usage examples on associate conditions and restarts:

(import (vicare)
  (only (vicare checks)
        with-result
        add-result))

;;Install a restart handler, establish an association between a
;;condition object and the restart object, call FIND-RESTART
;;with the condition argument, no restart objects without
;;association found, FIND-RESTART returns false.
;;
(let ((C (make-error)))
  (restart-case
      (with-condition-restarts C
        (list (find-restart 'alpha))
        (find-restart 'alpha C))
    ;;This is associated: it is skipped.
    (alpha (lambda () 1))))
⇒ #f

;;Install nested restart handlers with the same name, establish
;;an association between a condition object and the innermost
;;restart object, call FIND-RESTART with the condition argument,
;;invoke restart.
;;
(let ((C (make-error)))
  (restart-case
      (restart-case
          (with-condition-restarts C
            (list (find-restart 'alpha))
            (invoke-restart (find-restart 'alpha C)))
        ;;This is associated: it is skipped.
        (alpha (lambda () 1)))
    ;;This is not associated: it is selected.
    (alpha (lambda () 2))))
⇒ 2

;;Install a condition handler, install restart a handler and
;;establish an association between the raised condition object
;;and the restart object, search the restart, no matching
;;restart without association, SIGNAL returns.
;;
(with-return-to-signal-on-unhandled-exception
  (handler-bind
      ((&error (lambda (E)
                 (cond ((find-restart 'alpha E)
                        => invoke-restart)
                       (else #f)))))
    (restart-case
        (signal (make-error))
      ;;This is associated: it is skipped.
      (alpha (lambda ()
               (add-result 'restart-alpha)
               1)))
    123))
⇒ 123

;;Install a condition handler, install nested restart handlers
;;with the same name, establish an association between a raised
;;condition object and innermost restart object, invoke the
;;restart, the outermost restart is selected.
;;
(handler-bind
    ((&error (lambda (E)
               (invoke-restart (find-restart 'alpha E)))))
  (restart-case
      (restart-case
          (signal (make-error))
        ;;This is associated: it is skipped.
        (alpha (lambda () 1)))
    ;;This is not associated: it is selected.
    (alpha (lambda () 2))))
⇒ 2

Next: , Previous: , Up: restarts   [Index]