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
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
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
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.
(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 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).
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
catch form is either the value of the
throw happened, the value specified in the throw
Before exiting, the tag installed by this form is removed.
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
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:
Terminate the Librep interpreter, returning the value of the throw (if a number).
Exit the innermost event loop, unless currently in the outermost event loop, when control just passes back to the event loop.
As if a
SIGINT or C-c signal has been received. Control
passes back to the top-level event loop.
Triggered when a
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.