User Tools

A PCRE internal error occured. This might be caused by a faulty plugin

====== Macro CASE, CCASE, ECASE ====== ====Syntax==== * case //keyform {normal-clause}''*'' [otherwise-clause]// → //result''*''// * ccase //keyplace {normal-clause}''*''// → //result''*''// * ecase //keyform {normal-clause}''*''// → //result''*''// <blockquote> //normal-clause// ::= //(keys form''*'')// //otherwise-clause// ::= //({otherwise | t} form''*'')// //clause// ::= //normal-clause | otherwise-clause// </blockquote> ====Arguments and Values==== * //keyform// - a //[[CL:Glossary:form]]//; evaluated to produce a //test-key//. * //keyplace// - a //[[CL:Glossary:form]]//; evaluated initially to produce a //test-key//. Possibly also used later as a //[[CL:Glossary:place]]// if no //keys// match. * //test-key// - an object produced by evaluating //keyform// or //keyplace//. * //keys// - a //[[CL:Glossary:designator]]// for a //[[CL:Glossary:list]]// of //[[CL:Glossary:object|objects]]//. In the case of **case**, the //[[CL:Glossary:symbol|symbols]]// ''[[CL:Constant Variables: t]]'' and ''otherwise'' may not be used as the //keys// //[[CL:Glossary:designator]]//. To refer to these //[[CL:Glossary:symbol|symbols]]// by themselves as //keys//, the designators ''([[CL:Constant Variables: t]])'' and ''(otherwise)'', respectively, must be used instead. * //forms// - an //[[CL:Glossary:implicit progn]]//. * //results// - the //[[CL:Glossary:value|values]]// returned by the //forms// in the matching //clause//. ====Description==== These //[[CL:Glossary:macro|macros]]// allow the conditional execution of a body of //forms// in a //clause// that is selected by matching the //test-key// on the basis of its identity. The //keyform// or //keyplace// is //[[CL:Glossary:evaluate|evaluated]]// to produce the //test-key//. Each of the //normal-clauses// is then considered in turn. If the //test-key// is the //[[CL:Glossary:same]]// as any //[[CL:Glossary:key]]// for that //clause//, the //forms// in that //clause// are //evaluated// as an //[[CL:Glossary:implicit progn]]//, and the //[[CL:Glossary:value|values]]// it returns are returned as the value of the **case**, **ccase**, or **ecase** //[[CL:Glossary:form]]//. These //[[CL:Glossary:macro|macros]]// differ only in their //[[CL:Glossary:behavior]]// when no //normal-clause// matches; specifically: ===case=== If no //normal-clause// matches, and there is an //otherwise-clause//, then that //otherwise-clause// automatically matches; the //forms// in that //clause// are //evaluated// as an //[[CL:Glossary:implicit progn]]//, and the //[[CL:Glossary:value|values]]// it returns are returned as the value of the **case**. If there is no //otherwise-clause//, **case** returns **[[CL:Constant Variables:nil]]**. ===ccase=== If no //normal-clause// matches, a //[[CL:Glossary:correctable]]// //[[CL:Glossary:error]]// of type **[[CL:Types:type-error]]** is signaled. The offending datum is the //test-key// and the expected type is //[[CL:Glossary:type equivalent]]// to ''(member //key1// //key2// ...)''. The //[[CL:Glossary:restart]]// **[[CL:Restarts:store-value]]** can be used to correct the error. If the //[[CL:Glossary:restart]]// **[[CL:Restarts:store-value]]** is invoked, its //[[CL:Glossary:argument]]// becomes the new //test-key//, and is stored in //keyplace// as if by ''(setf //keyplace// //test-key//)''. Then **ccase** starts over, considering each //clause// anew. The subforms of //keyplace// might be evaluated again if none of the cases holds. ===ecase=== If no //normal-clause// matches, a //[[CL:Glossary:non-correctable]]// //[[CL:Glossary:error]]// of type **[[CL:Types:type-error]]** is signaled. The offending datum is the //test-key// and the expected type is //[[CL:Glossary:type equivalent]]// to ''([[CL:Types:member]] //key1// //key2// ...)''. Note that in contrast with **ccase**, the caller of **ecase** may rely on the fact that **ecase** does not return if a //normal-clause// does not match. ====Examples==== <blockquote> ([[CL:Macros:dolist]] (k '(1 2 3 :four #\v () [[CL:Constant Variables:t]] 'other)) ([[CL:Functions:format]] [[CL:Constant Variables:t]] "~S " (case k ((1 2) 'clause1) (3 'clause2) ([[CL:Constant Variables:nil]] 'no-keys-so-never-seen) (([[CL:Constant Variables:nil]]) 'nilslot) ((:four #\v) 'clause4) (([[CL:Constant Variables:t]]) 'tslot) (otherwise 'others)))) <o>CLAUSE1 CLAUSE1 CLAUSE2 CLAUSE4 CLAUSE4 NILSLOT TSLOT OTHERS </o> <r>[[CL:Constant Variables:NIL]] </r> ([[CL:Macros:defun]] add-em (x) ([[CL:Functions:apply]] #'[[CL:Functions:math-add|+]] ([[CL:Functions:mapcar]] #'decode x))) <r>ADD-EM </r> ([[CL:Macros:defun]] decode (x) (ccase x ((i uno) 1) ((ii dos) 2) ((iii tres) 3) ((iv cuatro) 4))) <r>DECODE </r> (add-em '(uno iii)) <r>4 </r> (add-em '(uno iiii)) <e>Error: The value of X, IIII, is not I, UNO, II, DOS, III, TRES, IV, or CUATRO. 1: Supply a value to use instead. 2: Return to Lisp Toplevel. Debug> :CONTINUE 1 Value to evaluate and use for X: 'IV</e> <r>5</r> </blockquote> ====Side Effects==== The debugger might be entered. If the //[[CL:Glossary:restart]]// **[[CL:Restarts:store-value]]** is invoked, the //[[CL:Glossary:value]]// of //keyplace// might be changed. ====Affected By==== **ccase** and **ecase**, since they might signal an error, are potentially affected by existing //handlers// and **[[CL:Variables:*debug-io*]]**. ====Exceptional Situations==== **ccase** and **ecase** signal an error of type **[[CL:Types:type-error]]** if no //normal-clause// matches. ====See Also==== * **[[CL:Macros:cond|Macro COND]]** * **[[CL:Macros:typecase|Macro TYPECASE]]** * **[[CL:Macros:setf|Macro SETF]]** * {\secref\GeneralizedReference} ====Notes==== <blockquote> (case //test-key// {((//key''*''//) //form''*''//)}''*'') ≡ ([[CL:Special Operators:let]] ((#1=#:g0001 //test-key//)) ([[CL:Macros:cond]] {(([[CL:Functions:member]] #1# '(//key''*''//)) //form''*''//)}''*'')) </blockquote> The specific error message used by **ecase** and **ccase** can vary between implementations. In situations where control of the specific wording of the error message is important, it is better to use **case** with an //otherwise-clause// that explicitly signals an error with an appropriate message.