PLTSchemeの「エラー」機能に驚いています。ゼロによる除算がある場合、それ以外の再帰は行われず、呼び出しスタックから出てエラーが発生します。
すべての関数の前に暗黙の継続がありますか?エラーはコールスタックを破棄しますか?誰かがこれについて何か考えを持っていますか?
PLTSchemeの「エラー」機能に驚いています。ゼロによる除算がある場合、それ以外の再帰は行われず、呼び出しスタックから出てエラーが発生します。
すべての関数の前に暗黙の継続がありますか?エラーはコールスタックを破棄しますか?誰かがこれについて何か考えを持っていますか?
PLT スキームでは、プロシージャエラーにより、エラー文字列を含む例外exn:failが発生します。すべての定義に「暗黙のキャッチ」はありません。次のサンプルを見てください。
;; test.ss
(define (a d)
(printf "~a~n" (/ 10 d)))
(a 0) ;; The interpreter will exit here.
(printf "OK~n")
コマンドラインから上記のスクリプトを実行すると、次のような出力後にインタープリターが存在することがわかります
/: division by zero
=== context ===
/home/user/test.ss:1:0: a
例外がユーザー プログラム内で処理されない場合、デフォルト ハンドラが処理するコア インタープリタまで伝搬されます。つまり、例外を出力して終了します。つまり、インタプリタは「例外が発生し、対処方法がわからないので終了します」と言うだけです。これは、JVM やその他の仮想マシンが例外を処理する方法と大差ありません。
PLT スキームの例外処理メカニズムの詳細については、MzScheme 言語マニュアルのwith-handlersとdynamic-windをお読みください。これらを使用して、Java の try-catch-finally ブロックをエミュレートすることもできます。
(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))))))
上記を可能にした構文拡張は次のとおりです。
;; 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 ...)))))