2009-10-13 9 views
5

Me sorprende la función "error" en PLTScheme. Si tengo una división por cero, no hace ninguna otra recursión y simplemente sale de la pila de llamadas y me da un error.¿Cómo funciona PLTScheme Catch errors?

¿Hay una continuación implícita antes de todas las funciones? ¿El error tirar la pila de llamadas? ¿Alguien tiene alguna idea sobre esto?

Respuesta

6

En el Esquema PLT, el error de procedimiento plantea la excepción EXN : fallan, que contiene una cadena de error. No hay una "captura implícita" para todas las definiciones. Mira el siguiente ejemplo:

;; test.ss 
(define (a d) 
    (printf "~a~n" (/ 10 d))) 

(a 0) ;; The interpreter will exit here.  
(printf "OK~n") 

Ejecutar la secuencia de comandos desde la línea de comandos y verá el intérprete existente después de imprimir algo así como

/: division by zero 

=== context === 
/home/user/test.ss:1:0: a 

Si una excepción no se maneja dentro del programa de usuario, se propaga hasta el intérprete principal donde un manejador predeterminado se ocupa de él, es decir, imprime la excepción y sale. En otras palabras, el intérprete simplemente dice: "se formuló una excepción y no sé cómo manejarla, así que me estoy retirando". Esto no es muy diferente de cómo la JVM o alguna otra máquina virtual manejan excepciones.

Para obtener más información sobre el mecanismo de manejo de excepciones de PLT Scheme, por favor leer sobre con-manipuladores y -dinámica del viento en el MzScheme Language Manual. Utilizándolos, puedes incluso emular el bloque try-catch-finally de 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)))))) 

Aquí es la extensión sintaxis que hizo posible lo anterior:

;; 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

Esto no era lo que estaba buscando. En Scheme, la mayoría de las funciones verifican automáticamente la división por cero y otros errores, ¿cómo ocurre eso? ¿La captura está implícita en todas las definiciones? – unj2

+0

@kunjaan He actualizado mi respuesta. –