1

I have a Scheme application that accepts some user input, computes, and gives some output. I would like to make it more robust by enabling some kind of error handling and a way to exit smoothly. Call with current continuation seems to be the thing to fill this gap here, but I'm not quite sure how to go about implementing it.

As of now, if the user enters some non-valid input, the program will crash and exit. I would simply like to keep the user in the application and give an error message instead. Here is an outline of my method, but I'm not sure where to implement it so that if an error occurs that would normally crash the system, just gives an error and keeps them in the program.

  (define (handle_err)
    (call/cc
     (lambda (a)
    (display "exception handled: a"))))

I would also like a clean exit from the program. That is, not a crash exit, nor a break. I would like the user to type "leave", have the program close and return to the interpreter. My outline looks much like the above, but it doesn't have the user leave the program, it just takes him back to the input prompt.

Any ideas are appreciated.

4

2 回答 2

1

Yes, call/cc can handle this kind of transfer of control. One problem here is that the call/cc corresponds to the "try/catch" in this example, not to the "throw".

A bigger problem, though, is that you don't have any nice way in r5rs to get control when an error occurs.

This is really just a symptom of an even bigger problem, which is that various different Scheme implementations have solved this problem in different ways.

Personally, I would strongly urge you to take a look at Racket; it's supported on many versions of Linux, lives in many standard distros, and handles this really nicely:

#lang racket

(with-handlers ([exn:fail?
                 (lambda (exn)
                   (display "oh noes! An exception occurred!"))])
  (try-something-dangerous))

(define (try-something-dangerous)
  (/ 1 0))

Actually, I would recommend Racket even if you want to write r5rs programs; you can just begin your programs with

#lang r5rs

... to get full r5rs compliance.

于 2012-11-11T23:51:34.477 回答
0

好吧,你看看这个方法

(define-syntax try
  (syntax-rules ()
        ((_ handler throw chunk)
         (call/cc (lambda (catch)
                (let ((throw (lambda (exc) (catch (handler exc)))))
                  chunk))))))
(define (div p q)
  (try 
    ;; Error processing
    (lambda (error) (printf "Error: ~s~n" error) error)

    ;; Error my be thrown with keyword "throw"
    throw

    ;;Actual code to run
     (if (= q 0)
    ;; Oh noes, error!
        (throw "Division by zero")
    ;; All ok, do the work
     (/ p q))))

(printf "1/0: ~s~n" (div 1 0))
(printf "1/2: ~s~n" (div 1 2))

“throw”用于捕获 throw 函数的名称(出于卫生考虑,这是需要的)。

于 2012-11-17T13:11:08.837 回答