2009-10-13 17 views
5

Sono stupito dalla funzione "errore" in PLTScheme. Se ho una divisione per zero, non fa alcuna altra ricorsione e esce dallo stack di chiamate e mi dà un errore.Come si verificano gli errori PLTScheme Catch?

C'è una continuazione implicita prima di tutte le funzioni? L'errore elimina lo stack delle chiamate? Qualcuno ha qualche idea su questo?

risposta

6

In PLT Scheme, l'errore di procedura di solleva l'eccezione Exn : non riescono, che contiene una stringa di errore. Non esiste alcuna "presa implicita" per tutte le definizioni. Guarda 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, viene propagato all'interprete principale in cui un gestore predefinito si occupa di esso, ovvero stampa l'eccezione ed esce. In altre parole, l'interprete dice semplicemente che "è stata sollevata un'eccezione e non so come gestirla, quindi sto smettendo". Questo non è molto diverso da come la JVM o qualche altra macchina virtuale gestiscono le eccezioni.

Per ulteriori informazioni su meccanismo di gestione delle eccezioni di PLT Scheme, si prega di leggere su con-gestori e dinamico vento nel MzScheme Language Manual. Usando questi, puoi persino emulare il blocco try-catch-finally di Java.

(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)))))) 

Qui è l'estensione della sintassi che ha fatto il possibile sopra:

;; 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 ...))))) 
+0

Questo non era quello che stava cercando. In Scheme, la maggior parte delle funzioni controlla automaticamente la divisione per zero e altri errori, come può accadere? L'implicito di cattura in tutti definisce? – unj2

+0

@kunjaan Ho aggiornato la mia risposta. –

Problemi correlati