GNU Info

Info Node: (librep.info)Catch and Throw

(librep.info)Catch and Throw


Next: Function Exits Up: Non-Local Exits
Enter node , (file) or (file)node

Catch and Throw
...............

   The `catch' and `throw' structures are used to perform explicit
transfers of control. First a `catch' form is used to setup a "tag";
this acts like a label for a `goto' statement.  To transfer control a
`throw' form is then used to transfer to the named tag. The tag is
destroyed and the `catch' form exits with the value provided by the
`throw'.

   In a program this looks like,

     (catch 'TAG
       ;; Forms which may `throw' back to TAG
       ...
       (throw 'TAG VALUE)
       ;; Control has now passed to the `catch',
       ;; no more forms in this progn will be evaluated.
       ...)
         => VALUE

where TAG is the tag to be used (this is normally a symbol) and VALUE
is the result of the `catch' form.

   When a throw actually happens all catches in scope are searched for
one with a tag which is `eq' to the tag in the throw. If more than one
exists the innermost is selected. Now that the catch has been located
the environment is `wound-back' to the catch's position (i.e. local
variables are unbound, cleanup forms executed, unused catches removed,
etc...) and all Lisp constructs between the current point of control
and the catch are immediately exited.

   For example,

     (let
         ((test 'outer))
       (cons (catch 'foo
               (let
                   ((test 'inner))
                 (throw 'foo test)
                 (setq test 'unreachable)))  ;Never reached
             test))
         => (inner . outer)

when the throw executes the second binding of `test' is unwound and the
first binding comes back into effect. For more details on variable
binding see Note: Local Variables.

   Note that catch tags are _dynamically_ scoped, the thrower does not
have to be within the same lexical scope (this means that you can
`throw' through functions).

 - Macro: catch tag body-forms...
     This special form defines a catch tag which will be accessible
     while the BODY-FORMS are evaluated.

     TAG is evaluated and recorded as the tag for this catch. Next the
     BODY-FORMS are evaluated as an implicit `progn'. The value of the
     `catch' form is either the value of the `progn', or, if a `throw'
     happened, the value specified in the THROW form.

     Before exiting, the tag installed by this form is removed.

 - Function: throw tag #!optional catch-value
     This function transfers the point of control to the catch form
     with a tag which is `eq' to TAG. The value returned by this catch
     form is either CATCH-VALUE or false if CATCH-VALUE is undefined.

     If there is no catch with a tag of TAG an error is signalled and
     the interpreter returns to the top-level of evaluation.

   There are a number of pre-defined throw tags:

`quit'
     Terminate the `librep' interpreter, returning the value of the
     throw (if a number).

`exit'
     Exit the innermost event loop, unless currently in the outermost
     event loop, when control just passes back to the event loop.

`user-interrupt'
     As if a `SIGINT' or `C-c' signal has been received. Control passes
     back to the top-level event loop.

`term-interrupt'
     Triggered when a `SIGTERM' or `SIGHUP' signal is received.  Tries
     to clean up any existing state, then terminates the interpreter.

   Note that it is the event loop that catches these tags. If no event
loop is active (i.e. just in read-eval-print on the console mode), any
uncaught throws will result in termination.


automatically generated by info2www version 1.2.2.9