The 'catch' and throw special forms allow for non-local exits and traps without going through the intermediate evaluations and function returns. If there is a 'catch' for a 'tag-symbol' that has no throw performed to it, 'catch' returns the value returned from 'expr'. If there is no 'expr', a NIL is returned. If a throw is evaluated with no corresponding 'catch', an error is generated:
error: no target for THROW
If, in the calling process, more than one 'catch' is set up for the same 'tag-symbol', the most recently evaluated 'tag-symbol' will be the one that does the actual catching.
(catch 'mytag) ; returns NIL - no THROW (catch 'mytag (+ 1 (+ 2 3))) ; returns 6 - no THROW (catch 'mytag (+ 1 (throw 'mytag))) ; returns NIL - caught it (catch 'mytag (+ 1 (throw 'mytag 55))) ; returns 55 - caught it (catch 'mytag (throw 'foo)) ; error: no target for THROW (defun in (x) ; define IN (if (numberp x) (+ x x) ; if number THEN double (throw 'math 42))) ; ELSE throw 42 (defun out (x) ; define OUT (princ "<") (princ (* (in x) 2)) ; double via multiply (princ ">") "there") (defun main (x) ; define MAIN (catch 'math (out x))) ; with CATCH (in 5) ; returns 10 (out 5) ; prints <20> returns "there" (main 5) ; prints <20> returns "there" (main 'a) ; prints < returns 42
Note: Although 'catch' and throw will accept a 'tag-symbol' that is not a symbol, it will not find this improper 'tag-symbol'. An error will be generated:
error: no target for THROW
See the
catch
special form in the