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.