User Tools


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

Link to this comparison view

cl:special_operators:throw [2017/05/01 21:00] (current)
Line 1: Line 1:
 +====== Special Operator THROW ======
 +  * **throw** //tag result-form//​
 +====Arguments and Values====
 +  * //tag// - a //​[[CL:​Glossary:​catch tag]]//; evaluated.
 +  * //​result-form//​ - a //​[[CL:​Glossary:​form]]//;​ evaluatedspecial.
 +**throw** causes a non-local control transfer to a **[[CL:​Special Operators:​catch]]** whose tag is **[[CL:​Functions:​eq]]** to //tag//.
 +//tag// is evaluated first to produce an //​[[CL:​Glossary:​object]]//​ called the throw tag; then //​result-form//​ is evaluated, and its results are saved. If the //​result-form//​ produces multiple values, then all the values are saved. The most recent outstanding **[[CL:​Special Operators:​catch]]** whose //tag// is **[[CL:​Functions:​eq]]** to the throw tag is exited; the saved results are returned as the value or values of **[[CL:​Special Operators:​catch]]**.
 +The transfer of control initiated by **throw** is performed as described in \secref\TransferOfControl.
 +<​blockquote> ​
 +([[CL:​Special Operators:​catch]] '​result ​
 +  ([[CL:​Special Operators:​let]] ((i 0) (j 0)) 
 +    ([[CL:​Macros:​loop]] ​
 +      ([[CL:​Macros:​incf]] j 3) 
 +      ([[CL:​Macros:​incf]] i) 
 +      ([[CL:​Macros:​when]] ([[CL:​Functions:​math-equal|=]] i 3) 
 +        (throw '​result ([[CL:​Functions:​values]] i j)))))) <r>3
 +        9</r>
 +        ​
 +([[CL:​Special Operators:​catch]] [[CL:​Constant Variables:​nil]]
 +  ([[CL:​Special Operators:​unwind-protect]]
 +      (throw [[CL:​Constant Variables:​nil]] 1) 
 +    (throw [[CL:​Constant Variables:​nil]] 2))) → 2 
 +([[CL:​Special Operators:​catch]] 'foo
 +  ([[CL:​Functions:​format]] [[CL:​Constant Variables:​t]] "The inner catch returns ~s.~%"
 +    ([[CL:​Special Operators:​catch]] '​foo ​
 +      ([[CL:​Special Operators:​unwind-protect]] ​
 +          (throw 'foo :​first-throw) ​
 +        (throw 'foo :​second-throw))))
 +  :​outer-catch)
 +<​o>​The inner catch returns :​SECOND-THROW </o>
 +The consequences of the following are undefined because the **[[CL:​Special Operators:​catch]]** of ''​b''​ is passed over by the first **throw**, hence portable programs must assume that its //​[[CL:​Glossary:​dynamic extent]]// is terminated. The //​[[CL:​Glossary:​binding]]//​ of the //​[[CL:​Glossary:​catch tag]]// is not yet //​[[CL:​Glossary:​disestablished]]//​ and therefore it is the target of the second **throw**.
 +([[CL:​Special Operators:​catch]] '​a ​
 +  ([[CL:​Special Operators:​catch]] '​b ​
 +    ([[CL:​Special Operators:​unwind-protect]] ​
 +        (throw 'a 1) 
 +      (throw 'b 2))))
 +====Affected By====
 +====Exceptional Situations====
 +If there is no outstanding //​[[CL:​Glossary:​catch tag]]// that matches the throw tag, no unwinding of the stack is performed, and an error of type **[[CL:​Types:​control-error]]** is signaled. When the error is signaled, the //​[[CL:​Glossary:​dynamic environment]]//​ is that which was in force at the point of the **throw**.
 +====See Also====
 +  * **[[CL:​Special Operators:​block|Special Operator BLOCK]]**
 +  * **[[CL:​Special Operators:​catch|Special Operator CATCH]]**
 +  * **[[CL:​Special Operators:​return-from|Special Operator RETURN-FROM]]**
 +  * **[[CL:​Special Operators:​unwind-protect|Special Operator UNWIND-PROTECT]]**
 +  * {\secref\Evaluation}
 +**[[CL:​Special Operators:​catch]]** and **throw** are normally used when the //​[[CL:​Glossary:​exit point]]// must have //​[[CL:​Glossary:​dynamic scope]]// (//e.g.// the **throw** is not lexically enclosed by the **[[CL:​Special Operators:​catch]]**),​ while **[[CL:​Special Operators:​block]]** and **[[CL:​Special Operators:​return]]** are used when //​[[CL:​Glossary:​lexical scope]]// is sufficient.