Common Lisp the Language, 2nd Edition

Next: Miscellaneous Features Up: Errors Previous: Specialized Error-Signaling Forms

# 24.3. Special Forms for Exhaustive Case Analysis

The syntax for `etypecase` and `ctypecase` is the same as for `typecase`, except that no `otherwise` clause is permitted. Similarly, the syntax for `ecase` and `ccase` is the same as for `case` except for the `otherwise` clause.

`etypecase` and `ecase` are similar to `typecase` and `case`, respectively, but signal a non-continuable error rather than returning `nil` if no clause is selected.

`ctypecase` and `ccase` are also similar to `typecase` and `case`, but signal a continuable error if no clause is selected.

[Macro]
`etypecase keyform {(type {form}*)}*`

This control construct is similar to `typecase`, but no explicit `otherwise` or `t` clause is permitted. If no clause is satisfied, `etypecase` signals an error with a message constructed from the clauses. It is not permissible to continue from this error. To supply an application-specific error message, the user should use `typecase` with an `otherwise` clause containing a call to `error`. The name of this function stands for ``exhaustive type case'' or ``error-checking type case.'' For example:

    (setq x 1/3)
    (etypecase x
      (integer x)
      (symbol (symbol-value x)))
    Error: The value of X, 1/3, is neither
           an integer nor a symbol.
    >

X3J13 voted in June 1988 (CONDITION-SYSTEM) to adopt a proposal for a Common Lisp Condition System. This proposal modifies the definition of `etypecase` to specify its interaction with the condition system. See section 29.4.3.

[Macro]
`ctypecase keyplace {(type {form}*)}*`

This control construct is similar to `typecase`, but no explicit `otherwise` or `t` clause is permitted. The keyplace must be a generalized variable reference acceptable to `setf`. If no clause is satisfied, `ctypecase` signals an error with a message constructed from the clauses. Continuing from this error causes `ctypecase` to accept a new value from the user, store it into keyplace, and start over, making the type tests again. Subforms of keyplace may be evaluated multiple times. The name of this function stands for ``continuable exhaustive type case.''

X3J13 voted in June 1988 (CONDITION-SYSTEM) to adopt a proposal for a Common Lisp Condition System. This proposal modifies the definition of `ctypecase` to specify its interaction with the condition system. See section 29.4.3.

X3J13 voted in March 1988 (PUSH-EVALUATION-ORDER) to clarify order of evaluation (see section 7.2).

[Macro]
`ecase keyform {({({key}*) | key} {form}*)}*`

This control construct is similar to `case`, but no explicit `otherwise` or `t` clause is permitted. If no clause is satisfied, `ecase` signals an error with a message constructed from the clauses. It is not permissible to continue from this error. To supply an error message, the user should use `case` with an `otherwise` clause containing a call to `error`. The name of this function stands for ``exhaustive case'' or ``error-checking case.'' For example:

    (setq x 1/3)
    (ecase x
      (alpha (foo))
      (omega (bar))
      ((zeta phi) (baz)))
    Error: The value of X, 1/3, is not
           ALPHA, OMEGA, ZETA, or PHI.

X3J13 voted in June 1988 (CONDITION-SYSTEM) to adopt a proposal for a Common Lisp Condition System. This proposal modifies the definition of `ecase` to specify its interaction with the condition system. See section 29.4.3.

[Macro]
`ccase keyplace {({({key}*) | key} {form}*)}*`

This control construct is similar to `case`, but no explicit `otherwise` or `t` clause is permitted. The keyplace must be a generalized variable reference acceptable to `setf`. If no clause is satisfied, `ccase` signals an error with a message constructed from the clauses. Continuing from this error causes `ccase` to accept a new value from the user, store it into keyplace, and start over, making the clause tests again. Subforms of keyplace may be evaluated multiple times. The name of this function stands for ``continuable exhaustive case.''

X3J13 voted in June 1988 (CONDITION-SYSTEM) to adopt a proposal for a Common Lisp Condition System. This proposal modifies the definition of `ccase` to specify its interaction with the condition system. See section 29.4.3.

X3J13 voted in March 1988 (PUSH-EVALUATION-ORDER) to clarify order of evaluation (see section 7.2).

Rationale: The special forms `etypecase`, `ctypecase`, `ecase`, and `ccase` are included in Common Lisp, even though a user could write them himself using the other standard facilities provided, because it is likely that many users will want these. Common Lisp therefore provides a standard consistent set rather than allowing a variety of incompatible dialects to develop.

In addition, experience has shown that some Lisp programmers are too lazy to put an appropriate `otherwise` clause into every `case` statement to check for cases they didn't anticipate, even if they would agree that it will probably hurt them later. If an `otherwise` clause can be included very easily by adding one character to the name of the construct, it is perhaps more likely that programmers will take the trouble to do it.

The `e` versions do nothing more than supply automatically generated `otherwise` clauses, but correct implementation of the `c` versions requires some care. It is therefore especially important that the `c` versions be provided by the system so users don't have to puzzle them out on their own. Individual implementations may be able to do a better job of supporting these special forms, using their own idiosyncratic facilities, than can be done using the error-signaling facilities defined by Common Lisp.

Next: Miscellaneous Features Up: Errors Previous: Specialized Error-Signaling Forms