User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cl:macros:assert [2019/12/05 03:00]
cl:macros:assert [2019/12/15 06:00] (current)
Line 1: Line 1:
 +====== Macro ASSERT ======
 +
 +====Syntax====
 +  * **assert** //test-form [(place''​*''​) [datum-form argument-form''​*''​]]//​ → [[CL:​Constant Variables:​nil]]
 +
 +====Arguments and Values====
 +  * //​test-form//​ - a //​[[CL:​Glossary:​form]]//;​ always evaluated.
 +  * //place// - a //​[[CL:​Glossary:​place]]//;​ evaluated if an error is signaled.
 +  * //​datum-form//​ - a //​[[CL:​Glossary:​form]]//​ that evaluates to a //datum//. Evaluated each time an error is to be signaled, or not at all if no error is to be signaled.
 +  * //​argument-form//​ - a //​[[CL:​Glossary:​form]]//​ that evaluates to an //​argument//​. Evaluated each time an error is to be signaled, or not at all if no error is to be signaled.
 +  * //datum//, //​arguments//​ - //​[[CL:​Glossary:​designator|designators]]//​ for a //​[[CL:​Glossary:​condition]]//​ of default type **[[CL:​Types:​error]]**. (These //​[[CL:​Glossary:​designator|designators]]//​ are the result of evaluating //​datum-form//​ and each of the //​argument-forms//​.)
 +
 +====Description====
 +
 +**assert** assures that //​test-form//​ evaluates to //​[[CL:​Glossary:​true]]//​. If //​test-form//​ evaluates to //​[[CL:​Glossary:​false]]//,​ **assert** signals a //​[[CL:​Glossary:​correctable]]//​ //​[[CL:​Glossary:​error]]//​ (denoted by //datum// and //​arguments//​). Continuing from this error using the **[[CL:​Restarts:​continue]]** //​[[CL:​Glossary:​restart]]//​ makes it possible for the user to alter the values of the //places// before **assert** evaluates //​test-form//​ again. If the value of //​test-form//​ is //​[[CL:​Glossary:​non-nil]]//,​ **assert** returns **[[CL:​Constant Variables:​nil]]**.
 +
 +The //places// are //​[[CL:​Glossary:​generalized reference|generalized references]]//​ to data upon which //​test-form//​ depends, whose values can be changed by the user in attempting to correct the error. //​[[CL:​Glossary:​subform|Subforms]]//​ of each //place// are only evaluated if an error is signaled, and might be re-evaluated if the error is re-signaled (after continuing without actually fixing the problem).
 +
 +The order of evaluation of the //places// is not specified; see section {\secref\GenRefSubFormEval}.
 +
 +If a //place// //​[[CL:​Glossary:​form]]//​ is supplied that produces more values than there are store variables, the extra values are ignored. If the supplied //​[[CL:​Glossary:​form]]//​ produces fewer values than there are store variables, the missing values are set to **[[CL:​Constant Variables:​nil]]**.
 +
 +====Examples====
 +In the below example, we assert that the //​[[CL:​Glossary:​function]]//​ ''​really-matrix-multiply''​ is already defined and implements matrix multiplication.
 +<​blockquote>​
 +([[CL:​Macros:​defparameter]] *x* ([[CL:​Functions:​make-array]] '(3 5) :​initial-element 3)) <​r>​*X*</​r>​
 +([[CL:​Macros:​defparameter]] *y* ([[CL:​Functions:​make-array]] '(3 5) :​initial-element 7)) <​r>​*Y*</​r>​
 +*x* <​r>#​2A((3 3 3 3 3) (3 3 3 3 3) (3 3 3 3 3)) </r>
 +*y* <​r>#​2A((7 7 7 7 7) (7 7 7 7 7) (7 7 7 7 7)) </r>
 +([[CL:​Macros:​defun]] matrix-multiply (a b) 
 +  ([[CL:​Special Operators:​let]] (([[CL:​Variables:​star-print-array-star|*print-array*]] [[CL:​Constant Variables:​nil]])) ​
 +    (assert ([[CL:​Macros:​and]] ([[CL:​Functions:​math-equal|=]] ([[CL:​Functions:​array-rank]] a) ([[CL:​Functions:​array-rank]] b) 2) 
 +                 ​([[CL:​Functions:​math-equal|=]] ([[CL:​Functions:​array-dimension]] a 1) ([[CL:​Functions:​array-dimension]] b 0))) 
 +        (a b) "​Cannot multiply ~S by ~S." a b) 
 +    (really-matrix-multiply a b))) <​r>​MATRIX-MULTIPLY</​r>​
 +(matrix-multiply *x* *y*)
 +<​e>​Correctable error in MATRIX-MULTIPLY:​
 +Cannot multiply #<ARRAY ...> by #<ARRAY ...>.
 +Restart options:
 +1: You will be prompted for one or more new values.
 +2: Top level.
 +Debug> :continue 1
 +Value for A: *x*
 +Value for B: ([[CL:​Functions:​make-array]] '(5 3) :​initial-element 6)</​e>​
 +<​r>#​2A((54 54 54 54 54) 
 +    (54 54 54 54 54)
 +    (54 54 54 54 54)
 +    (54 54 54 54 54)
 +    (54 54 54 54 54))</​r>​
 +([[CL:​Macros:​defun]] double-safely (x) 
 +  (assert ([[CL:​Functions:​numberp]] x) (x))
 +  ([[CL:​Functions:​math-add|+]] x x)) <​r>​DOUBLE-SAFELY</​r>​
 +(double-safely 4) <​r>​8</​r>​
 +(double-safely [[CL:​Constant Variables:​t]])
 +<​e>​Correctable error in DOUBLE-SAFELY:​ The value of (NUMBERP X) must be non-NIL.
 +Restart options:
 +1: You will be prompted for one or more new values.
 +2: Top level.
 +Debug> :continue 1
 +Value for X: 7</e>
 +<​r>​14</​r>​
 +</​blockquote>​
 +
 +====Affected By====
 +**[[CL:​Variables:​star-break-on-signals-star|Variable *BREAK-ON-SIGNALS*]]**
 +
 +The set of active //​[[CL:​Glossary:​condition handlers]]//​.
 +
 +====Exceptional Situations====
 +None.
 +
 +====See Also====
 +**[[CL:​Macros:​check-type|Macro CHECK-TYPE]]**,​ **[[CL:​Functions:​error|Function ERROR]]**, {\secref\GeneralizedReference}
 +
 +====Notes====
 +The debugger need not include the //​test-form//​ in the error message, and the //places// should not be included in the message, but they should be made available for the user's perusal. If the user gives the "​continue"​ command, the values of any of the references can be altered. The details of this depend on the implementation'​s style of user interface.
 +
 +\issue{FORMAT-STRING-ARGUMENTS:​SPECIFY} \issue{ASSERT-ERROR-TYPE:​ERROR} \issue{PUSH-EVALUATION-ORDER:​FIRST-ITEM} \issue{SETF-MULTIPLE-STORE-VARIABLES:​ALLOW}