I think that the issue is that with-handlers calls it's handlers with
the continuation of the with-handlers expression itself, but
uncaught-exception-handler calls it's handlers with the continuation
at the point of the break. So in the with-handlers case, you have
already escaped out of the context where the exn happened, but you
didn't yet with uncaught-exception-handler. So you can do the escaping
jump in the latter case, but in the former, you'd have to jump back
"into" the body of the with-handlers and you don't have a real
continuation, so you can't do that.
You can use continuation-marks to explore the current context like this:
#lang racket
(with-continuation-mark 'key 0
(with-handlers ([exn?
(λ (x)
(printf ">> ~s\n" (continuation-mark-set->list
(current-continuation-marks)
'key))
(void))])
(with-continuation-mark 'key 1
(+ (with-continuation-mark 'key 2
(car))
1))))
(with-continuation-mark 'key 0
(let/ec k
(parameterize ([uncaught-exception-handler
(λ (exn)
(printf ">> ~s\n" (continuation-mark-set->list
(current-continuation-marks)
'key))
(k (void)))])
(with-continuation-mark 'key 1
(+ (with-continuation-mark 'key 2
(car))
1)))))
Robby
On Tue, Apr 28, 2015 at 8:48 AM, Greg Hendershott
<[email protected]> wrote:
> #lang racket/base
>
> ;;; Note: Run the following from command-line Racket (not DrRacket or
> ;;; racket-mode).
>
> ;;; [0] Something that runs long enough to give you a chance to break
>
> (define (long-loop)
> (displayln "Starting loop. Press CONTROL+C...")
> (for/sum ([i (in-range 1000000000)])
> 1))
>
> ;;; [1] exn:break-continuation works in uncaught-exception-handler
>
> (parameterize ([uncaught-exception-handler
> (let ([orig-ueh (uncaught-exception-handler)])
> (λ (e)
> (cond [(exn:break? e)
> (displayln "\nGot break! Calling
> exn:break-continuation")
> ((exn:break-continuation e))]
> [else (orig-ueh e)])))])
> (long-loop))
> ;; =>
> ;; Got break! Calling exn:break-continuation
> ;; 1000000000
>
> ;;; [2] exn:break-continuation does NOT work in with-handlers
>
> (with-handlers ([exn:break?
> (λ (e)
> (displayln "\nGot break! Calling exn:break-continuation")
> ((exn:break-continuation e)))])
> (long-loop))
> ;; Got break! Calling exn:break-continuation
> ;; continuation application: attempt to jump into an escape continuation
> ;; context...:
> ;; /usr/racket/collects/racket/private/more-scheme.rkt:162:2:
> select-handler/no-breaks
> ;; /home/greg/src/racket/break-continuation.rkt: [running body]
>
>
> ;;; Why?
>
> ;;
> ;; I think this is explained by the doc for error-escape-handler:
> ;;
> ;; "Due to a continuation barrier around exception-handling calls, an
> ;; error escape handler cannot invoke a full continuation that was
> ;; created prior to the exception, but it can abort to a prompt (see
> ;; call-with-continuation-prompt) or invoke an escape continuation
> ;; (see call-with-escape-continuation)."
> ;;
> ;; `with-handlers` is subject to this.
> ;; `uncaught-exception-handler` is not.
> ;;
> ;; However that was a little subtle for me. I think the doc for
> ;; exn:break-continuation should mention this explicitly. For example:
> ;; "Note: This won't work with `with-handlers`, you have to use it
> ;; from `uncaught-exception-handlers`!" Should I submit a PR with that
> ;; doc update?
> ;;
> ;; p.s. Interestingly the only example usage of exn:continuation-break
> ;; I was able to find, is the one in Racket's implementation of r6rs:
> ;;
> ;;
> https://github.com/racket/r6rs/blob/9e248e7591d9b01f67d964f905a9884fa5df5d69/r6rs-lib/rnrs/exceptions-6.rkt#L84
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.