Come funziona PLTScheme errori di cattura?
-
21-09-2019 - |
Domanda
Sono stupito dalla funzione "errore" in PLTScheme. Se ho una divisione per zero, si pretende molto fare qualsiasi altra ricorsione e appena esce dalla stack di chiamate e mi danno un errore.
C'è una continuazione implicita prima di tutte le funzioni? L'errore buttare via lo stack di chiamate? Qualcuno ha qualche idea su questo?
Soluzione
In PLT Scheme, la procedura di Errore solleva l'eccezione Exn: fail , che contiene una stringa di errore. Non v'è alcun "catturare implicita" per tutte le definisce. Guardate il seguente esempio:
;; test.ss
(define (a d)
(printf "~a~n" (/ 10 d)))
(a 0) ;; The interpreter will exit here.
(printf "OK~n")
Eseguire lo script sopra dalla riga di comando e vedrete l'interprete esistente dopo la stampa qualcosa come
/: division by zero
=== context ===
/home/user/test.ss:1:0: a
Se un'eccezione non viene gestita all'interno del programma utente, si è propagato fino a l'interprete principale in cui un gestore di default si occupa di esso, cioè stampare l'eccezione e di uscita. In altre parole, l'interprete dice solo, "un'eccezione è stata sollevata e non so come trattare con esso, quindi sono quiting". Questo non è molto diverso da come la JVM o qualche altra macchina virtuale gestire le eccezioni.
Per ulteriori informazioni su meccanismo di gestione delle eccezioni di PLT Scheme, si prega di leggere su con-gestori e dinamico-vento nella MzScheme Lingua manuale. L'utilizzo di questi, si può anche emulare 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))))))
Ecco l'estensione sintassi che ha reso possibile che questo possibile:
;; 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 ...)))))