Nikita Karetnikov <nik...@karetnikov.org> writes: > I’ve expected ‘with-exception-handler’ to behave like ‘catch’, but it > doesn’t. > > scheme@(guile-user)> ,use (srfi srfi-34) > scheme@(guile-user)> (with-exception-handler (const "got it") (lambda () > (raise "boom!"))) > ice-9/boot-9.scm:106:20: In procedure #<procedure 94b0e40 at > ice-9/boot-9.scm:97:6 (thrown-k . args)>: > ice-9/boot-9.scm:106:20: Throw to key `srfi-34' with args `("boom!")'. > > Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue. > scheme@(guile-user) [1]> > scheme@(guile-user)> (catch 'misc-error (lambda () (error "boom!")) (const > "got it")) > $1 = "got it" > > Is there an explanation that doesn’t involve diving into the land of > continuations and dynamic wind? I mean, when should I use the one but > not the other?
Neil's response was exactly correct, but it used some terminology that might be difficult for non-experts to understand, so I'm going to try my hand at a simpler explanation. When an exception is caught, there are two things that typically need to be done: 1. Run the user-specified handler. 2. Do a non-local exit back to the catch/guard/with-exception-handler, returning the value produced by the handler. 'catch' and 'guard' handle both of these steps for you. 'with-exception-handler' is a more powerful but lower-level mechanism. It handles step 1, but leaves step 2 to you. If you use it, it is your responsibility to handle the non-local exit yourself, typically by invoking a continuation. That's what the 'call/cc' and the call to 'k' was about in Neil's response. Having said all this, I think the shorter answer is that you should probably be using 'guard' instead. Regards, Mark