Next: , Previous: , Up: iklib syntaxes   [Index]


6.8.14 The try, catch, finally syntaxes

The syntax try can be used to handle raised exceptions in addition to the R6RS–defined syntaxes with-exception-handler and guard. The syntax is basically a wrapper for guard from (rnrs exceptions (6)) (see guard).

Syntax: try ?body ?catch-clauses
Syntax: try ?body ?catch-clauses ?finally-clause
Syntax: try ?body ?finally-clause
Auxiliary Syntax: catch
Auxiliary Syntax: finally
Auxiliary Syntax: else

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 ?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; and, or, xor, not are the identifiers exported by (vicare).

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:

Some usage examples without the finally clause:

(import (vicare))

(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:

(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: , Previous: , Up: iklib syntaxes   [Index]