;; test.ss
(define (a d)
(printf "~a~n" (/ 10 d)))
(a 0) ;; The interpreter will exit here.
(printf "OK~n")
Wykonać powyższy skrypt z linii poleceń i widać interpreter istniejący po wydrukowaniu coś podobnego
/: division by zero
=== context ===
/home/user/test.ss:1:0: a
Jeśli wyjątek nie jest obsługiwana w programie użytkownika, jest on propagowany do interpretera podstawowego, z którym traktuje go domyślny program obsługi, tj. wypisuje wyjątek i kończy działanie. Innymi słowy, tłumacz po prostu mówi: "Wyjątek został podniesiony i nie wiem jak sobie z tym poradzić, więc rezygnuję". Nie różni się to znacznie od tego, w jaki sposób maszyna JVM lub inna maszyna wirtualna obsługuje wyjątki.
Aby dowiedzieć się więcej na temat mechanizmu obsługi wyjątków schemacie PLT, przeczytaj o z-ładowarki i dynamicznego wiatru w MzScheme Language Manual. Używając ich, możesz nawet emulować blok próbny catch-finally Javy.
(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))))))
Oto rozszerzenie składni, które sprawiły, że powyższe możliwe:
;; 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 ...)))))
To nie było to, czego szukałem. W Scheme, większość funkcji automatycznie sprawdza dzielenie przez zero i inne błędy, jak to się dzieje? Czy połów jest ukryty we wszystkich definicjach? – unj2
@kunjaan Zaktualizowałem moją odpowiedź. –