Next: , Up: iklib compensations   [Index]


6.10.1 Basic compensations usage

A compensation is a chunk of code that undoes a resource allocation performed in another chunk, example:

(define port
  (open-file-input-port "/tmp/proof.1"))

must be ”compensated” by:

(close-port port)

with the compensations stack such code can be written:

(with-compensations
  (letrec
      ((port (compensate
                 (open-file-input-port "/tmp/proof.1")
               (with
                 (close-port port)))))
    (make-use-of port)))

or:

(with-compensations
  (define port
    (compensate
        (open-file-input-port "/tmp/proof.1")
      (with
        (close-port port))))
  (make-use-of port))

Compensation forms are embedded in a closure and pushed on a stack, so that, in case of error, it is possible to evaluate them in allocation–reversed order.

A form that makes use of a compensation stack looks like this:

(with-compensations
  (compensate
      ALLOC-FORMS-1
    (with RELEASE-FORMS-1))
  (compensate
      ALLOC-FORMS-2
    (with RELEASE-FORMS-2))
  BODY-FORMS)

both with-compensations and compensate are syntaxes. If no error occurs the order of evaluation is:

ALLOC-FORMS-1
ALLOC-FORMS-2
BODY-FORMS
RELEASE-FORMS-2
RELEASE-FORMS-1

if an error occurs in BODY-FORMS, the order of evaluation is:

ALLOC-FORMS-1
ALLOC-FORMS-2
BODY-FORMS
RELEASE-FORMS-2
RELEASE-FORMS-1

if an error occurs in ALLOC-FORMS-2, the order of evaluation is:

ALLOC-FORMS-1
ALLOC-FORMS-2
RELEASE-FORMS-1

if an error occurs in ALLOC-FORMS-1, the order of evaluation is:

ALLOC-FORMS-1

if an error occurs in RELEASE-FORMS-1, the order of evaluation is:

ALLOC-FORMS-1
ALLOC-FORMS-2
BODY-FORMS
RELEASE-FORMS-2
RELEASE-FORMS-1

if an error occurs in RELEASE-FORMS-2, the order of evaluation is:

ALLOC-FORMS-1
ALLOC-FORMS-2
BODY-FORMS
RELEASE-FORMS-2
RELEASE-FORMS-1

So with-compensations tries to evaluate all the release forms, despite errors. Of course if an error occurs in the middle of a set of forms:

(first-form)   ;evaluated
(raise 'here)
(third-form)   ;not evaluated

the forms before the error are evaluated, while the forms after the error are not.

A variant of with-compensations exists to evaluate the compensation forms only in case of error:

(with-compensations/on-error
  (compensate
      ALLOC-FORMS-1
    (with RELEASE-FORMS-1))
  (compensate
      ALLOC-FORMS-2
    (with RELEASE-FORMS-2))
  BODY-FORMS)

if no error occurs the order of evaluation is:

ALLOC-FORMS-1
ALLOC-FORMS-2
BODY-FORMS

while if an error occurs the evaluation is equal to the cases of with-compensations. The “on error” variant is useful in constructors and initialisation functions, where we want to run the compensations only if an error occurs; if no error is raised, we just want the constructor to return.


Next: , Up: iklib compensations   [Index]