我有一个Scheme应用程序,它接受一些用户输入,计算并提供一些输出。我希望通过启用某种错误处理和顺利退出的方式使其更加强大。呼叫当前延续似乎是填补这一空白的事情,但我不太确定如何实施它。
截至目前,如果用户输入了一些无效输入,程序将崩溃并退出。我只想将用户留在应用程序中并改为给出错误消息。这是我的方法的概述,但我不知道在哪里实现它,以便如果发生通常会使系统崩溃的错误,只需给出错误并将它们保留在程序中。
(define (handle_err)
(call/cc
(lambda (a)
(display "exception handled: a"))))
我还希望从程序中彻底退出。也就是说,不是崩溃退出,也不是休息。我希望用户输入“leave”,关闭程序并返回解释器。我的大纲看起来很像上面,但它没有用户离开程序,它只是让他回到输入提示。
任何想法都表示赞赏。
答案 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函数的名称(这是因为卫生而需要)。