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