[racket] understanding racket exceptions
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