Next: , Up: stdlib exceptions conditions   [Index]


5.7.2.1 Condition objects

Conceptually, there are two different kinds of condition objects: simple conditions and compound conditions. An object that is either a simple condition or a compound condition is simply a condition. Compound conditions form a type disjoint from the base types described in report section baselib types. A simple condition describes a single aspect of an exceptional situation. A compound condition represents multiple aspects of an exceptional situation as a list of simple conditions, its components. Most of the operations described in this section treat a simple condition identically to a compound condition with itself as its own sole component. For a subtype t of &condition, a condition of type t is either a record of type t or a compound condition containing a component of type t.

Condition Type: &condition

Simple conditions are records of subtypes of the &condition record type. The &condition type has no fields and is neither sealed nor opaque.

Procedure: condition condition1

The condition procedure returns a condition object with the components of the conditions as its components, in the same order, i.e., with the components of condition1 appearing first in the same order as in condition1, then with the components of condition2, and so on. The returned condition is compound if the total number of components is zero or greater than one. Otherwise, it may be compound or simple.

Procedure: simple-conditions condition

The simple-conditions procedure returns a list of the components of condition, in the same order as they appeared in the construction of condition. The returned list is immutable. If the returned list is modified, the effect on condition is unspecified.

NOTE Because condition decomposes its arguments into simple conditions, simple-conditions always returns a “flattened” list of simple conditions.

Procedure: condition? obj

Return #t if obj is a (simple or compound) condition, otherwise return #f.

Procedure: condition-predicate rtd

rtd must be a record–type descriptor of a subtype of &condition. The condition-predicate procedure returns a procedure that takes one argument. This procedure returns #t if its argument is a condition of the condition type represented by rtd, i.e., if it is either a simple condition of that record type (or one of its subtypes) or a compound conditition with such a simple condition as one of its components, and #f otherwise.

Procedure: condition-accessor rtd proc

rtd must be a record–type descriptor of a subtype of &condition. proc should accept one argument, a record of the record type of rtd. The condition-accessor procedure returns a procedure that accepts a single argument, which must be a condition of the type represented by rtd. This procedure extracts the first component of the condition of the type represented by rtd, and returns the result of applying proc to that component.

(define-record-type (&cond1 make-cond1 real-cond1?)
  (parent &condition)
  (fields
   (immutable x real-cond1-x)))

(define cond1?
  (condition-predicate
    (record-type-descriptor &cond1)))
(define cond1-x
  (condition-accessor
    (record-type-descriptor &cond1)
    real-cond1-x))

(define foo (make-cond1 'foo))

(condition? foo)                        ⇒ #t
(cond1? foo)                            ⇒ #t
(cond1-x foo)                           ⇒ foo

(define-record-type (&cond2 make-cond2 real-cond2?)
  (parent &condition)
  (fields
   (immutable y real-cond2-y)))

(define cond2?
  (condition-predicate
    (record-type-descriptor &cond2)))
(define cond2-y
  (condition-accessor
     (record-type-descriptor &cond2)
     real-cond2-y))

(define bar (make-cond2 'bar))

(condition? (condition foo bar))        ⇒ #t
(cond1? (condition foo bar))            ⇒ #t
(cond2? (condition foo bar))            ⇒ #t
(cond1? (condition foo))                ⇒ #t
(real-cond1? (condition foo))           ⇒ unspecified
(real-cond1? (condition foo bar))       ⇒ #f
(cond1-x (condition foo bar))           ⇒ foo
(cond2-y (condition foo bar))           ⇒ bar

(equal? (simple-conditions (condition foo bar))
        (list foo bar))                 ⇒ #t

(equal? (simple-conditions
          (condition foo (condition bar)))
        (list foo bar))                 ⇒ #t
Syntax: define-condition-type ?condition-type ?supertype ?constructor ?predicate ?field-spec1

?condition-type, ?supertypes, ?constructor, and ?predicate must all be identifiers. Each ?field-spec must be of the form

(?field ?accessor)

where both ?field and ?accessor must be identifiers.

The define-condition-type form expands into a record–type definition for a record type ?condition-type. The record type will be non–opaque, non–sealed, and its fields will be immutable. It will have ?supertype has its parent type. The remaining identifiers will be bound as follows:

(define-condition-type &c &condition
  make-c c?
  (x c-x))

(define-condition-type &c1 &c
  make-c1 c1?
  (a c1-a))

(define-condition-type &c2 &c
  make-c2 c2?
  (b c2-b))
(define v1 (make-c1 "V1" "a1"))

(c? v1)        ⇒ #t
(c1? v1)       ⇒ #t
(c2? v1)       ⇒ #f
(c-x v1)       ⇒ "V1"
(c1-a v1)      ⇒ "a1"
(define v2 (make-c2 "V2" "b2"))

(c? v2)        ⇒ #t
(c1? v2)       ⇒ #f
(c2? v2)       ⇒ #t
(c-x v2)       ⇒ "V2"
(c2-b v2)      ⇒ "b2"
(define v3 (condition
             (make-c1 "V3/1" "a3")
             (make-c2 "V3/2" "b3")))

(c? v3)        ⇒ #t
(c1? v3)       ⇒ #t
(c2? v3)       ⇒ #t
(c-x v3)       ⇒ "V3/1"
(c1-a v3)      ⇒ "a3"
(c2-b v3)      ⇒ "b3"
(define v4 (condition v1 v2))

(c? v4)        ⇒ #t
(c1? v4)       ⇒ #t
(c2? v4)       ⇒ #t
(c-x v4)       ⇒ "V1"
(c1-a v4)      ⇒ "a1"
(c2-b v4)      ⇒ "b2"
(define v5 (condition v2 v3))

(c? v5)        ⇒ #t
(c1? v5)       ⇒ #t
(c2? v5)       ⇒ #t
(c-x v5)       ⇒ "V2"
(c1-a v5)      ⇒ "a3"
(c2-b v5)      ⇒ "b2"

Next: , Up: stdlib exceptions conditions   [Index]