(rontolisp) docs
← Special Forms

catch

(catch tag body...)

Establishes a dynamic exit point named by tag and returns the value of the last body form -- or, if a throw to an eq tag fires anywhere in the body's dynamic extent, the thrown value. The tag is an ordinary runtime value evaluated once on entry (usually a quoted symbol), so unlike block/return-from the thrower does not need the catcher in lexical scope: it only has to run while the catch is active. The innermost active catch with a matching tag wins; a non-matching one lets the exit pass through.

catch/throw work on every backend except --no-gc (a compile error there). On the wasm-GC backends (Preview 1 and --component) they compile through the WebAssembly exception-handling proposal, so running a program that uses them needs wasmtime 37+ with -W exceptions=y, exactly like unwind-protect and handler-case.

A throw is a non-local exit, not a condition: it unwinds through a handler-case without being caught, while every intervening unwind-protect cleanup does run.

The exit crosses function boundaries, which is what makes it useful for bailing out of a callback:

Tags are compared with eq, so a freshly consed tag matches only itself: