User Tools


Differences

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

Link to this comparison view

cl:special_operators:catch [2019/09/14 05:00]
cl:special_operators:catch [2019/09/22 06:00] (current)
Line 1: Line 1:
 +====== Special Operator CATCH ======
 +
 +====Syntax====
 +  * **catch** //tag form''​*''//​ → //​result''​*''//​
 +
 +====Arguments and Values====
 +  * //tag// - a //​[[CL:​Glossary:​catch tag]]//; evaluated.
 +  * //forms// - an //​[[CL:​Glossary:​implicit progn]]//.
 +  * //results// - if the //forms// exit normally, the //​[[CL:​Glossary:​value|values]]//​ returned by the //forms//; if a throw occurs to the //tag//, the //​[[CL:​Glossary:​value|values]]//​ that are thrown.
 +
 +====Description====
 +**catch** is used as the destination of a non-local control transfer by **[[CL:​Special Operators:​throw]]**. //Tags// are used to find the **catch** to which a **[[CL:​Special Operators:​throw]]** is transferring control. ''​(catch 'foo ''​form''​)''​ catches a ''​(throw 'foo ''​form''​)''​ but not a ''​(throw 'bar ''​form''​)''​.
 +
 +The order of execution of **catch** follows:
 +
 +  * 1. //tag// is evaluated. It serves as the name of the **catch**.
 +  * 2. //forms// are then evaluated as an implicit **[[CL:​Special Operators:​progn]]**,​ and the results of the last //form// are returned unless a **[[CL:​Special Operators:​throw]]** occurs.
 +  * 3. If a **[[CL:​Special Operators:​throw]]** occurs during the execution of one of the //forms//, control is transferred to the **catch** //​[[CL:​Glossary:​form]]//​ whose //tag// is **[[CL:​Functions:​eq]]** to the tag argument of the **[[CL:​Special Operators:​throw]]** and which is the most recently established **catch** with that //tag//. No further evaluation of //forms// occurs.
 +  * 4. The //tag// //​[[CL:​Glossary:​established]]//​ by **catch** is //​[[CL:​Glossary:​disestablished]]//​ just before the results are returned.
 +
 +--------
 +  ​
 +If during the execution of one of the //forms//, a **[[CL:​Special Operators:​throw]]** is executed whose tag is **[[CL:​Functions:​eq]]** to the **catch** tag, then the values specified by the **[[CL:​Special Operators:​throw]]** are returned as the result of the dynamically most recently established **catch** form with that tag.
 +
 +The mechanism for **catch** and **[[CL:​Special Operators:​throw]]** works even if **[[CL:​Special Operators:​throw]]** is not within the lexical scope of **catch**. **[[CL:​Special Operators:​throw]]** must occur within the //​[[CL:​Glossary:​dynamic extent]]// of the //​[[CL:​Glossary:​evaluation]]//​ of the body of a **catch** with a corresponding //tag//.
 +
 +====Examples==== ​
 +<​blockquote>​
 +(catch '​dummy-tag 1 2 ([[CL:​Special Operators:​throw]] '​dummy-tag 3) 4) <​r>​3</​r>​
 +(catch '​dummy-tag 1 2 3 4) <​r>​4</​r>​
 +([[CL:​Macros:​defun]] throw-back (tag) ([[CL:​Special Operators:​throw]] tag [[CL:​Constant Variables:​t]])) <​r>​THROW-BACK</​r>​
 +(catch '​dummy-tag (throw-back '​dummy-tag) 2) <​r>​T</​r>​
 +</​blockquote>​
 +
 +In the below example, we contrast **catch** behavior with corresponding example of **[[CL:​Special Operators:​block]]**. ​
 +
 +<​blockquote>​
 +(catch '​c ​
 +  ([[CL:​Special Operators:​flet]] ((c1 () ([[CL:​Special Operators:​throw]] 'c 1)))
 +    (catch 'c (c1) ([[CL:​Functions:​print]] '​unreachable)) 2)) <r>2 </r>
 +</​blockquote>​
 +====Affected By====
 +None. 
 +
 +====Exceptional Situations==== ​
 +An error of type **[[CL:​Types:​control-error]]** is signaled if **[[CL:​Special Operators:​throw]]** is done when there is no suitable **catch** //​tag//​. ​
 +
 +====See Also====
 +  * **[[CL:​Special Operators:​throw|Special Operator THROW]]**
 +  * {\secref\Evaluation}
 +
 +====Notes====
 +It is customary for //​[[CL:​Glossary:​symbol|symbols]]//​ to be used as //tags//, but any //​[[CL:​Glossary:​object]]//​ is permitted. However, numbers should not be used because the comparison is done using **[[CL:​Functions:​eq]]**.
 +
 +**catch** differs from **[[CL:​Special Operators:​block]]** in that **catch** tags have dynamic //​[[CL:​Glossary:​scope]]//​ while **[[CL:​Special Operators:​block]]** names have //​[[CL:​Glossary:​lexical scope]]//.