#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.

Reply via email to