Next: syntaxes blocking, Previous: syntaxes returnable, Up: syntaxes [Contents][Index]
try
syntaxWe can use syntax try
to handle raised exceptions in addition to the syntaxes
with-exception-handler
and guard
; the syntax is basically a wrapper for guard
,
but with the limitation that the raised object must be a condition object defined with
define-condition-object
.
Evaluate the form ?body and return its results. If no exceptions are raised by ?body: before returning evaluate the ?finally-clause. If an exception is raised by ?body: handle it with the ?catch-clauses and, before returning, evaluate the ?finally-clause.
The auxiliary syntaxes catch
, finally
and else
are matched with their
symbol name.
The ?catch-clauses argument must have the format:
(catch ?var ?catch-clause0 ?catch-clause ...)
where ?var must be an identifier and every ?catch-clause has one of the forms:
(?pred ?tag-body0 ?tag-body ...) (else ?else-body0 ?else-body ...)
where the optional else
clause must appear only once as last one. The ?pred argument
must have one of the following recursive formats:
?pred = (?tag) | (and ?inner-pred0 ?inner-pred ...) | (or ?inner-pred0 ?inner-pred ...) | (xor ?inner-pred0 ?inner-pred ...) | (not ?inner-pred) ?inner-pred = ?tag | (and ?inner-pred0 ?inner-pred ...) | (or ?inner-pred0 ?inner-pred ...) | (xor ?inner-pred0 ?inner-pred ...) | (not ?inner-pred)
where: ?tag is a condition object type identifier; the auxiliary syntaxes and
,
or
, xor
, not
are matches by their symbol name.
The ?finally-clause must have the format:
(finally ?finally-body0 ?finally-body ...)
when the finally
clause is present: the ?body is wrapped into an unwind–protection
syntax, See The unwind-protection mechanism.
The following expansions take place:
(try ?body (catch ?var ((?tag) ?tag-body0 ?tag-body ...) ...)) → (guard (?var ((is-a? ?var) ?tag-body0 ?tag-body ...) ...) ?body)
(try ?body (catch ?var ((?tag) ?tag-body0 ?tag-body ...) ...) (else ?else-body0 ?else-body ...)) → (guard (?var ((is-a? ?var ?tag0) ?tag-body0 ?tag-body ...) ... (else ?else-body0 ?else-body ...)) ?body)
(try ?body (catch ?var ((?tag) ?tag-body0 ?tag-body ...) ...) (finally ?finally-body0 ?finally-body ...)) → (with-unwind-protection (lambda (dummy) ?finally-body0 ?finally-body ...) (lambda () (guard (?var ((is-a? ?var ?tag0) ?tag-body0 ?tag-body ...) ...) ?body)))
(try ?body (finally ?finally-body0 ?finally-body ...)) → (with-unwind-protection (lambda (dummy) ?finally-body0 ?finally-body ...) (lambda () ?body))
Some usage examples without the finally
clause:
(define-condition-type &this &error make-this-condition condition-this? (a condition-this.a) (b condition-this.b) (c condition-this.c)) (define (doit thunk) (try (thunk) (catch E ((&this) (list (condition-this.a E) (condition-this.b E) (condition-this.c E))) ((&message) (condition-message E)) (else E)))) (doit (lambda () (raise (make-this-condition 1 2 3)))) ⇒ (1 2 3) (doit (lambda () (raise (make-message-condition "ciao")))) ⇒ "ciao" (doit (lambda () (raise 123))) ⇒ 123
Evaluation order tracking for finally
clauses:
(import (only (mmck checks) with-result add-result)) (with-result (try (add-result 'body) (catch E ((&error) (add-result 'catch-error)) ((&warning) (add-result 'catch-warning)) (else (add-result 'catch-else))) (finally (add-result 'finally)))) ⇒ (body (body finally)) (with-result (try (begin (add-result 'body) (raise (make-warning))) (catch E ((&error) (add-result 'catch-error)) ((&warning) (add-result 'catch-warning)) (else (add-result 'catch-else))) (finally (add-result 'finally)))) ⇒ (catch-warning (body catch-warning finally))
Next: syntaxes blocking, Previous: syntaxes returnable, Up: syntaxes [Contents][Index]
This document describes version 0.1.0-devel.1 of MMCK Exceptional Conditions.