Next: iklib compensations api, Up: iklib compensations [Index]
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: iklib compensations api, Up: iklib compensations [Index]