[racket] understanding racket exceptions

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Sep 4 10:26:05 EDT 2010

The current exception handler really is determined by a continuation
mark and not by a parameter (i.e., a mark that is separate from the one
that determines the current parameterization).

At Fri, 3 Sep 2010 13:03:04 -0600, Jay McCarthy wrote:
> That's my understanding of it too. [Maybe modulo parameters rather
> than marks themselves.]
> 
> Jay
> 
> On Fri, Sep 3, 2010 at 12:05 PM, Danny Yoo <dyoo at cs.wpi.edu> wrote:
> > I'm about to try replicating Racket's exception system in WeScheme, so
> > I want to make sure I understood the model beforehand.  Here's my
> > understanding of the system, and if people can correct me, I'd greatly
> > appreciate it!
> >
> >
> > * Exception handlers are managed by keeping a chain of these handlers
> > within the continuation marks.  A form like with-handlers effectively
> > extends the chain within its dynamic extent.  There's a designated
> > continuation-marks key used to keep track of exception handlers.  This
> > key is internal and otherwise inaccessible to the outside world.  Let
> > me call this key "K" for the moment.  If it were possible to get at K,
> > then hypothetically I would be able to observe it by doing something
> > like this:
> >
> >  (begin
> >    (printf "Before: ~s~n" (continuation-mark-set->list
> > (current-continuation-marks) K))
> >    (with-handlers ([exn void])
> >       (printf "Within: ~s~n" (continuation-mark-set->list
> > (current-continuation-marks) K)))
> >
> >
> > * Whenever an exception happens, the runtime immediately grabs the
> > current continuation marks and extracts the chain of exception
> > handlers associated to K.  It then walks the chain.  Each element in
> > the chain is responsible for returning the exception up the chain.  If
> > an exception handler knows what to do with an exception, and wants to
> > interrupt the chain, then it is supposed to call the
> > error-escape-handler to stop the rest of the computation.
> >
> >
> > I looked at the exceptions proposal [Friedman95
> > http://www.cs.indiana.edu/scheme-repository/doc.proposals.exceptions.html
> > ].  I see that the proposal defines a current-exception-handlers, but
> > I don't see such a function in Racket.  I assume that the only way to
> > adjust the current exception handler is through
> > call-with-exception-handler.
> >
> >
> >
> > If I wanted to simulate the exception-handling mechanism, it might
> > look something like this:
> >
> > 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;
> > #lang racket
> >
> > (define K (cons "my-distinguished"
> >                "exception key!"))
> >
> >
> > (define-syntax (simulate stx)
> >  (syntax-case stx ()
> >    [(_ body ...)
> >     (syntax/loc stx
> >       (call-with-exception-handler my-exception-handler
> >                                    (lambda ()
> >                                      body ...)))]))
> >
> >
> > (define (my-uncaught-exception-handler exn)
> >  (printf "I am the uncaught exception handler, seeing ~s~n" exn)
> >  (abort-current-continuation (default-continuation-prompt-tag) void))
> >
> >
> > (define (my-exception-handler exn)
> >  (printf "my-exception-handler\n")
> >  (let ([handlers
> >         (continuation-mark-set->list (current-continuation-marks)
> >                                      K)])
> >    (printf "I see the following handlers: ~s\n" handlers)
> >    (let ([exn
> >           (foldl (lambda (a-handler exn)
> >                    (a-handler exn))
> >                  exn
> >                  handlers)])
> >
> >      ;; At this point, calls the uncaught-exception-handler if none of the
> >      ;; handlers will support us.
> >      (printf "Uncaught exception handler kicking in.\n")
> >      (my-uncaught-exception-handler exn)
> >      (printf "I should never see this!\n"))))
> >
> >
> > (define-syntax (my-with-handlers stx)
> >  (syntax-case stx ()
> >    [(_ ([exn-test? on-exn]
> >         ...)
> >        body ...)
> >     (syntax/loc stx
> >       ;; NOTE: I need to make sure the with-continuation-mark is not
> > in tail position,
> >       ;; or else my t2 shows that an exception handlers has been
> > replaced, rather than nested.
> >       (let ([result
> >              (with-continuation-mark K (lambda (exn)
> >                                          (cond
> >                                            [(exn-test? exn)
> >                                             (on-exn exn)
> >                                             (abort-current-continuation
> >                                              
> (default-continuation-prompt-tag)
> >                                              void)]
> >                                            ...
> >                                            [else
> >                                             exn]))
> >
> >                (begin body ...))])
> >         result))]))
> >
> >
> > ;; test1: see that I can catch an exception
> > (define (t1)
> >  (simulate (my-with-handlers ((exn:fail? (lambda (exn)
> >                                            (printf "Oh!  I see ~s~n" exn))))
> >                              (printf "Starting up~n")
> >                              (/ 1 0))))
> >
> > ;; test2: see that I can observe the nesting, and also fire off the
> > uncaught exception handler
> > (define (t2)
> >  (simulate (my-with-handlers ()
> >                              (printf "Starting up~n")
> >                              (my-with-handlers ()
> >                                                (/ 1 0)))))
> > 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> > _________________________________________________
> >  For list-related administrative tasks:
> >  http://lists.racket-lang.org/listinfo/users
> >
> 
> 
> 
> -- 
> Jay McCarthy <jay at cs.byu.edu>
> Assistant Professor / Brigham Young University
> http://teammccarthy.org/jay
> 
> "The glory of God is Intelligence" - D&C 93
> _________________________________________________
>   For list-related administrative tasks:
>   http://lists.racket-lang.org/listinfo/users


Posted on the users mailing list.