2012-11-11 40 views
1

我有一個Scheme應用程序,它接受一些用戶輸入,計算並給出一些輸出。我希望通過啓用某種錯誤處理和順利退出的方式使其更加強大。目前的延續呼叫似乎是填補這一空白的一個方面,但我不太清楚如何去實施它。方案調用/ cc處理錯誤

截至目前,如果用戶輸入一些無效的輸入,程序將崩潰並退出。我只想將用戶保留在應用程序中,而不是提供錯誤消息。下面是我的方法的概要,但我不確定在哪裏實現它,以便如果發生錯誤會導致系統崩潰,只是給出錯誤並將它們保存在程序中。

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

我也想從程序中徹底退出。也就是說,不是崩潰退出,也不是休息。我希望用戶輸入「離開」,關閉程序並返回到解釋器。我的大綱看起來很像上面的,但它沒有用戶離開程序,它只是把他帶回到輸入提示符。

任何想法表示讚賞。

+0

您使用的是什麼Scheme實現? –

+0

我正在使用r5rs。 – Matt

+0

R5RS是Scheme的標準。您使用的是R5RS的哪些實施?這很重要,因爲各種實現具有衝突的異常系統,並且針對您的問題的解決方案在這些實現之間有所不同。 –

回答

1

是的,call/cc可以處理這種控制轉移。這裏的一個問題是call/cc對應於本例中的「try/catch」,而不是「throw」。

但是,一個更大的問題是,當發生錯誤時,您在r5rs中沒有任何好的方法來獲得控制權。

這實際上只是一個更大問題的症狀,即各種不同的Scheme實現以不同的方式解決了這個問題。

就我個人而言,我強烈建議您看看Racket;它支持Linux的許多版本,住在許多標準發行版,並處理這個真的很好:其實

#lang racket 

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

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

,我會建議球拍,即使你想寫R5RS方案;你可以開始你的程序與

#lang r5rs 

...獲得完整r5rs合規。

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)) 

的「扔」用於捕捉拋函數名(這是需要,因爲衛生)。