scheme call / cc用于处理错误

时间:2012-11-11 09:42:57

标签: scheme r5rs

我有一个Scheme应用程序,它接受一些用户输入,计算并提供一些输出。我希望通过启用某种错误处理和顺利退出的方式使其更加强大。呼叫当前延续似乎是填补这一空白的事情,但我不太确定如何实施它。

截至目前,如果用户输入了一些无效输入,程序将崩溃并退出。我只想将用户留在应用程序中并改为给出错误消息。这是我的方法的概述,但我不知道在哪里实现它,以便如果发生通常会使系统崩溃的错误,只需给出错误并将它们保留在程序中。

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

我还希望从程序中彻底退出。也就是说,不是崩溃退出,也不是休息。我希望用户输入“leave”,关闭程序并返回解释器。我的大纲看起来很像上面,但它没有用户离开程序,它只是让他回到输入提示。

任何想法都表示赞赏。

2 个答案:

答案 0 :(得分: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程序,我也会推荐Racket;你可以用

开始你的程序
#lang r5rs

...以获得完整的合规性。

答案 1 :(得分: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函数的名称(这是因为卫生而需要)。