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?

È stato utile?

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 ...)))))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top