How does PLTScheme Catch errors?
I am amazed by the "error" function in PLTScheme. If I have a division by zero, it doesnt do any other recursion and just comes out of the call stack and give me an error.
Is there an implicit continuation before all the functions? Does the error throw away the call stack?开发者_C百科 Does anybody have any idea about this?
In PLT Scheme, the procedure error raises the exception exn:fail, which contains an error string. There is no "implicit catch" for all defines. Look at the following sample:
;; test.ss
(define (a d)
(printf "~a~n" (/ 10 d)))
(a 0) ;; The interpreter will exit here.
(printf "OK~n")
Execute the above script from the command line and you will see the interpreter existing after printing something like
/: division by zero
=== context ===
/home/user/test.ss:1:0: a
If an exception is not handled within the user program, it is propagated up to the core interpreter where a default handler deals with it, i.e print the exception and exit. In other words, the interpreter just says, "an exception was raised and I don't know how to deal with it, so I am quiting". This is not much different from how the JVM or some other virtual machine handle exceptions.
To learn more about PLT Scheme's exception handling mechanism, please read about with-handlers and dynamic-wind in the MzScheme Language Manual. Using these, you can even emulate Java's try-catch-finally block.
(define (d a b)
(try
(printf "~a~n" (/ a b))
(catch (lambda (ex)
(printf "Error: ~a" ex)))
(finally
(if (> b -2)
(d a (sub1 b))))))
Here is the syntax extension that made the above possible:
;; try-catch-finally on top of with-handlers and dynamic-wind.
(define-syntax try
(syntax-rules (catch finally)
((_ try-body ... (catch catch-proc))
(with-handlers (((lambda (ex) #t)
(lambda (ex)
(catch-proc ex))))
(begin
try-body ...)))
((_ try-body ... (catch catch-proc) (finally fin-body ...))
(dynamic-wind
(lambda () ())
(lambda ()
(with-handlers (((lambda (ex) #t)
(lambda (ex)
(catch-proc ex))))
(begin
try-body ...)))
(lambda () fin-body ...)))
((_ try-body ... (finally fin-body ...))
(dynamic-wind
(lambda () ())
(lambda () try-body ...)
(lambda () fin-body ...)))))
精彩评论