XLISP catch, throw

Nyquist / XLISP 2.0 - Contents | Tutorials | Examples | Reference

# catch, throw

Type: | - | special form (fsubr)
Source: | - | xlcont.c, xljump.c

## Syntax

(catch tag-symbol [expr ... ])
  tag-symbol - an expression that evaluates to a symbol
  expr - an optional series of expressions to be evaluated
  returns - the value of the last expression the throw expression

(throw tag-symbol [expr])
  tag-symbol - an expression that evaluates to a symbol
  expr - an optional expression to be returned
  returns - never returns

## Description

The 'catch' and 'throw' special forms allow for non-local exits and traps without going through the intermediate evaluations and function returns:

    (catch tag-symbol
      [expr ...]
      (throw tag-symbol [expr]))

If there is a 'catch' for a 'tag-symbol' that has no 'throw' performed to it, 'catch' returns the value returned from 'expr':

    > (catch 'mytag
        (+ 1 (+ 2 3)))
    6

If there is no 'expr', NIL is returned:

    > (catch 'mytag)
    NIL

The 'expr' in 'throw' specifies what value is to be returned by the corresponding 'catch':

    > (catch 'mytag
        (+ 1 (throw 'mytag 55)))
    55

If there is no 'expr' in 'throw', NIL is returned to the corresponding 'catch':

    > (catch 'mytag
        (throw 'mytag))
    NIL

If 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
        (catch 'mytag
          (throw 'mytag))
        (print 'hello))
    HELLO

If a 'throw' is evaluated with no corresponding 'catch', an error is signalled:

    > (catch 'mytag
        (throw 'foo))
    error: no target for THROW

## Examples

    (defun in (x)
      (if (numberp x)           ; if X is a number
          (+ x x)               ; then double X
          (throw 'math 42)))    ; else throw 42

    (defun out (x)
      (princ "<")
      (princ  (* (in x) 2))     ; double via multiply
      (princ ">")
      "there")

    (defun main (x)
      (catch 'math (out x)))    ; catch the throw from IN

    > (in 5)
    10       ; return value

    > (out 5)
    <20>     ; screen output of PRINC
    "there"  ; return value

    > (main 5)
    <20>     ; screen output of PRINC
    "there"  ; return value

    > (main 'a)
    <        ; screen output of PRINC
    42       ; return value

See + , * , defun, if , numberp, princ.

Note: 'catch' and 'throw' accept not only symbols as 'tag-symbol', but if a 'tag-symbol' cannot be compared via eql, an error is signalled:

    > (catch "mytag"
        (throw "mytag"))
    error: no target for THROW

This was reproduced with Nyquist 3.03 in December 2010.

See also:

- Contents → Control Constructs

Back to Top

Nyquist / XLISP 2.0 - Contents | Tutorials | Examples | Reference